Spring開發(fā)中自定義注解的使用詳解
Spring自定義注解
在Java項目中,可以自定義注解,方便進行某些處理操作,提供開發(fā)效率。
比如,在進行實體類的crud操作時,一般都有create_time, createUser, updateTime, updateUser這幾個字段,而且不是核心業(yè)務代碼,這時可以引入注解簡化開發(fā)和提高效率。
比如下面這段代碼:
//實體類的新增操作 public void save(CategoryDTO categoryDTO) { //.................................... //設置創(chuàng)建時間、修改時間、創(chuàng)建人、修改人 category.setCreateTime(LocalDateTime.now()); category.setUpdateTime(LocalDateTime.now()); category.setCreateUser(BaseContext.getCurrentId()); category.setUpdateUser(BaseContext.getCurrentId()); categoryMapper.insert(category); }
如果都按照上述的操作方式來處理這些公共字段, 需要在每一個業(yè)務方法中進行操作, 編碼相對冗余、繁瑣,那能不能對于這些公共字段在某個地方統(tǒng)一處理,來簡化開發(fā)呢?
以下以自定義注解AutoFill為例,使用AOP切面編程,實現(xiàn)功能增強,來完成公共字段自動填充功能。 說明如何自定義注解,和使用注解
實現(xiàn)步驟:
- 自定義注解 AutoFill,用于標識需要進行公共字段自動填充的方法
- 自定義切面類 AutoFillAspect,統(tǒng)一攔截加入了 AutoFill 注解的方法,通過反射為公共字段賦值
- 在 Mapper 的方法上加入 AutoFill 注解
1. 引入maven依賴
<dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjrt</artifactId> <version>1.9.4</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.9.4</version> </dependency>
2. 自定義注解
package com.zsx.annotation; import com.zsx.enumeration.OperationType; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * 自定義注解,用于標識某個方法需要進行功能字段自動填充處理 */ @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface AutoFill { //數(shù)據庫操作類型:UPDATE INSERT OperationType value(); }
枚舉類OperationType
package com.zsx.enumeration; /** * 數(shù)據庫操作類型 */ public enum OperationType { /** * 更新操作 */ UPDATE, /** * 插入操作 */ INSERT }
3. 自定義切面
package com.zsx.aspect; import com.zsx.annotation.AutoFill; import com.zsx.constant.AutoFillConstant; import com.zsx.context.BaseContext; import com.zsx.enumeration.OperationType; import lombok.extern.slf4j.Slf4j; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; import org.aspectj.lang.reflect.MethodSignature; import org.springframework.stereotype.Component; import java.lang.reflect.Method; import java.time.LocalDateTime; /** * 自定義切面,實現(xiàn)公共字段自動填充處理邏輯 */ @Aspect @Component @Slf4j public class AutoFillAspect { /** * 切入點 */ @Pointcut("execution(* com.sky.mapper.*.*(..)) && @annotation(com.sky.annotation.AutoFill)") public void autoFillPointCut(){} /** * 前置通知,在通知中進行公共字段的賦值 */ @Before("autoFillPointCut()") public void autoFill(JoinPoint joinPoint){ log.info("開始進行公共字段自動填充..."); //獲取到當前被攔截的方法上的數(shù)據庫操作類型 MethodSignature signature = (MethodSignature) joinPoint.getSignature();//方法簽名對象 AutoFill autoFill = signature.getMethod().getAnnotation(AutoFill.class);//獲得方法上的注解對象 OperationType operationType = autoFill.value();//獲得數(shù)據庫操作類型 //獲取到當前被攔截的方法的參數(shù)--實體對象 Object[] args = joinPoint.getArgs(); if(args == null || args.length == 0){ return; } Object entity = args[0]; //準備賦值的數(shù)據 LocalDateTime now = LocalDateTime.now(); Long currentId = BaseContext.getCurrentId(); //根據當前不同的操作類型,為對應的屬性通過反射來賦值 if(operationType == OperationType.INSERT){ //為4個公共字段賦值 try { Method setCreateTime = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_CREATE_TIME, LocalDateTime.class); Method setCreateUser = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_CREATE_USER, Long.class); Method setUpdateTime = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_TIME, LocalDateTime.class); Method setUpdateUser = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_USER, Long.class); //通過反射為對象屬性賦值 setCreateTime.invoke(entity,now); setCreateUser.invoke(entity,currentId); setUpdateTime.invoke(entity,now); setUpdateUser.invoke(entity,currentId); } catch (Exception e) { e.printStackTrace(); } }else if(operationType == OperationType.UPDATE){ //為2個公共字段賦值 try { Method setUpdateTime = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_TIME, LocalDateTime.class); Method setUpdateUser = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_USER, Long.class); //通過反射為對象屬性賦值 setUpdateTime.invoke(entity,now); setUpdateUser.invoke(entity,currentId); } catch (Exception e) { e.printStackTrace(); } } } }
AutoFillConstant 常量類
package com.zsx.reggie.constant; /** * 公共字段自動填充相關常量 */ public class AutoFillConstant { /** * 實體類中的方法名稱 */ public static final String SET_CREATE_TIME = "setCreateTime"; public static final String SET_CREATE_USER = "setCreateUser"; public static final String SET_UPDATE_TIME = "setUpdateTime"; public static final String SET_UPDATE_USER = "setUpdateUser"; }
4. 使用注解
在Mapper接口的方法上加入 AutoFill 注解
package com.sky.mapper; @Mapper public interface CategoryMapper { /** * 插入數(shù)據 * @param category */ @Insert("insert into category(type, name, sort, status, create_time, update_time, create_user, update_user)" + " VALUES" + " (#{type}, #{name}, #{sort}, #{status}, #{createTime}, #{updateTime}, #{createUser}, #{updateUser})") @AutoFill(value = OperationType.INSERT) void insert(Category category); /** * 根據id修改分類 * @param category */ @AutoFill(value = OperationType.UPDATE) void update(Category category); }
完成,這樣在每次插入和更新操作的時候,就可以自動設置更新時間和更新人id。 (不過要注意,這里的sql語句中的這幾個字段還是不能缺少)
到此這篇關于Spring開發(fā)中自定義注解的使用詳解的文章就介紹到這了,更多相關Spring自定義注解內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Java中bcrypt算法實現(xiàn)密碼加密的方法步驟
我們可以在Spring Boot和SSM中實現(xiàn)密碼加密,使用bcrypt算法可以保障密碼的安全性,并且減少了手動編寫哈希函數(shù)的工作量,本文就來詳細的介紹一下,感興趣的可以了解一下2023-08-08Spring Cloud @RefreshScope 原理及使用
這篇文章主要介紹了Spring Cloud @RefreshScope 原理及使用,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-01-01Spring boot中filter類不能注入@Autowired變量問題
這篇文章主要介紹了Spring boot中filter類不能注入@Autowired變量問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-09-09