SpringBoot實現(xiàn)公共字段自動填充的方法步驟
問題引入
JavaEE開發(fā)的時候,新增字段,修改字段大都會涉及到創(chuàng)建時間(createTime),更改時間(updateTime),創(chuàng)建人(craeteUser),更改人(updateUser),如果每次都要自己去setter(),會比較麻煩,可以使用Spring的AOP,對于任意Insert,Update操作進行增強
解決步驟
主要依賴
如果使用了springboot,那就只需要導入這一個,這個框架對spring自帶的aop框架進行了優(yōu)化封裝,更好用
事實上,還需要兩個依賴,spring-context和spring-aop,不過springboot自帶的有
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.4</version>
</dependency>
注釋代碼
給那些新增、修改功能中的設(shè)置時間、修改人的代碼部分注釋掉

自定義注解&使用
封裝數(shù)據(jù)庫操作類型
/**
* 數(shù)據(jù)庫操作類型
*/
public enum OperationType {
/**
* 更新操作
*/
UPDATE,
/**
* 插入操作
*/
INSERT
}自定義注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface AutoFill {
// 數(shù)據(jù)庫操作類型:UPDATE INSERT
OperationType value();
}給需要自動填充的方法加上注解
/**
* 新增員工
* @param employee
*/
@Insert("INSERT INTO employee" +
"(name, username, password, phone, sex, id_number, create_time, update_time, create_user, update_user)" +
"VALUES" +
"(#{name}, #{username}, #{password}, #{phone}, #{sex}, #{idNumber}, #{createTime}, #{updateTime}, #{createUser}, #{updateUser})")
@AutoFill(value = OperationType.INSERT)
void insert(Employee employee);
/**
* 修改員工信息
* @param employee
*/
@AutoFill(value = OperationType.UPDATE)
void update(Employee employee);
/**
* 根據(jù)ID查詢員工
* @param id
* @return
*/
@Select("SELECT * FROM employee WHERE id = #{id}")
Employee getById(Long id);
/**
* 密碼修改
* @param passwordEditDTO
*/
@AutoFill(value = OperationType.UPDATE)
@Update("UPDATE employee SET `password` = #{newPassword} WHERE `id` = #{empId} AND `password` = #{oldPassword}")
void updatePwd(PasswordEditDTO passwordEditDTO);通知類
@Slf4j
@Component
@Aspect
public class AutoFillAspect {
/**
* 切面 && 指定切入點
*/
@Pointcut("execution(* com.sky.mapper.*.*(..)) && @annotation(com.sky.annotation.AutoFill)")
public void autoFillPointCut(){}
/**
* 切面 && 此方法(autoFill()) 在切入點之前執(zhí)行
* @param joinPoint
*/
@Before("autoFillPointCut()")
public void autoFill(JoinPoint joinPoint) {
log.info("開始進行公共字段自動填充...");
// 拿到當前被攔截的方法上的數(shù)據(jù)庫操作類型
MethodSignature signature = (MethodSignature)joinPoint.getSignature();// 拿到實現(xiàn)類的簽名信息,不過我們只需要方法的簽名信息,強轉(zhuǎn)成MethodSignature
AutoFill autoFill = signature.getMethod().getAnnotation(AutoFill.class);// 獲得簽名對象的注解對象
OperationType operationType = autoFill.value(); // 拿到數(shù)據(jù)庫操作類型
// 拿到當前被攔截方法的方法參數(shù)(新增、更改方法的參數(shù)一般都是實體類)
Object[] args = joinPoint.getArgs();
if (args == null || args.length == 0){ // 防止null,防止空參
return;
}
Object entity = args[0]; // 這一行就要求,以后的新增、更改方法參數(shù),實體類必須寫在首形參位置
// 需填充的數(shù)據(jù)
LocalDateTime now = LocalDateTime.now();
Long currentId = BaseContext.getCurrentId();
// 根據(jù)當前不同的操作類型,使用反射為對應的屬性賦值
if (operationType == OperationType.INSERT) {
// 為4個公共字段賦值
try {
Method setCreateTime = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_CREATE_TIME, LocalDateTime.class);
Method setUpdateTime = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_TIME, LocalDateTime.class);
Method setCreateUser = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_CREATE_USER, Long.class);
Method setUpdateUser = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_USER, Long.class);
// 通過反射給對象屬性賦值
setCreateTime.invoke(entity, now);
setUpdateTime.invoke(entity, now);
setCreateUser.invoke(entity, currentId);
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();
}
}
}
}依賴相關(guān)類
公共字段自動填充相關(guān)常量
/**
* 公共字段自動填充相關(guān)常量
*/
public class AutoFillConstant {
/**
* 實體類中的方法名稱
*/
public static final String SET_CREATE_TIME = "setCreateTime";
public static final String SET_UPDATE_TIME = "setUpdateTime";
public static final String SET_CREATE_USER = "setCreateUser";
public static final String SET_UPDATE_USER = "setUpdateUser";
}線程空間上下文
public class BaseContext {
public static ThreadLocal<Long> threadLocal = new ThreadLocal<>();
public static void setCurrentId(Long id) {
threadLocal.set(id);
}
public static Long getCurrentId() {
return threadLocal.get();
}
public static void removeCurrentId() {
threadLocal.remove();
}
}啟動類加上注解@EnableAspectJAutoProxy
@SpringBootApplication
@EnableTransactionManagement //開啟注解方式的事務(wù)管理
@EnableAspectJAutoProxy // 開啟注解方式的AOP
@Slf4j
public class SkyApplication {
public static void main(String[] args) {
SpringApplication.run(SkyApplication.class, args);
log.info("server started");
}
}在這段代碼中,joinPoint 是 Spring AOP 中的一個概念,表示連接點,即在程序執(zhí)行過程中切入的某個點。Signature 則是 Signature 接口的實現(xiàn)類之一,用于表示連接點的簽名信息,包括方法名、參數(shù)列表等。
具體來說,這段代碼的含義是從 joinPoint 中獲取連接點的簽名信息,并將其強制轉(zhuǎn)換為 MethodSignature 類型。然后可以通過 signature 對象獲取連接點(被代理方法)的詳細信息,比如方法名、參數(shù)類型等。
例如,可以通過 signature.getMethod().getName() 獲取連接點方法的名稱,通過 signature.getParameterTypes() 獲取連接點方法的參數(shù)類型數(shù)組等。
需要注意的是,在實際應用中,我們使用這段代碼時需要確保 joinPoint 真正代表了一個方法連接點,否則在強制轉(zhuǎn)換為 MethodSignature 時可能會拋出類型轉(zhuǎn)換異常。

到此這篇關(guān)于SpringBoot實現(xiàn)公共字段自動填充的方法步驟的文章就介紹到這了,更多相關(guān)SpringBoot公共字段自動填充內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java聊天室之實現(xiàn)運行服務(wù)器與等待客戶端連接
這篇文章主要為大家詳細介紹了Java簡易聊天室之實現(xiàn)運行服務(wù)器程序與等待客戶端程序連接功能,文中的示例代碼講解詳細,需要的可以了解一下2022-10-10
SpringAMQP消息隊列(SpringBoot集成RabbitMQ方式)
這篇文章主要介紹了SpringAMQP消息隊列(SpringBoot集成RabbitMQ方式),具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-04-04
java實現(xiàn)遠程連接執(zhí)行命令行與上傳下載文件
這篇文章主要介紹了java實現(xiàn)遠程連接執(zhí)行命令行與上傳下載文件方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-05-05
spring使用Filter過濾器對Response返回值進行修改的方法
這篇文章主要介紹了spring使用Filter過濾器對Response返回值進行修改,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-09-09
JAVA實現(xiàn)漢字轉(zhuǎn)拼音功能代碼實例
這篇文章主要介紹了JAVA實現(xiàn)漢字轉(zhuǎn)拼音功能代碼實例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2020-05-05
SpringBoot項目運行一段時間后自動關(guān)閉的坑及解決
這篇文章主要介紹了SpringBoot項目運行一段時間后自動關(guān)閉的坑及解決方案,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-09-09

