JAVA通過反射獲取實體屬性變更記錄日志信息


  項目中某些地方要求記錄信息變更日志,通過反射獲取屬性對比新舊信息的變化情況,然后記錄日志

一、創建實體類比較標志注解(只比較有注解的屬性)

 1 import java.lang.annotation.*;
 2 
 3 /**
 4  * @Description //實體類比較標志注解
 5  * @Author yangli
 6  **/
 7 @Documented
 8 @Target(ElementType.FIELD)
 9 @Retention(RetentionPolicy.RUNTIME)
10 public @interface BeanContrast {
11 
12     String fieldDesc() default "undefined";
13 
14 }

二、創建變更信息實體

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * @Description //實體修改信息類 
 **/
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class ModifyInfo {

@BeanContrast(fidldDesc="修改字段")
private String modifyField;
@BeanContrast(fidldDesc="修改前")
private String beforeModify;

    @BeanContrast(fidldDesc="修改后")
private String afterModify;

}

三、創建工具類

 1 import lombok.extern.slf4j.Slf4j;
 2 import org.apache.commons.lang3.StringUtils;
 3 
 4 import java.beans.PropertyDescriptor;
 5 import java.lang.reflect.Field;
 6 import java.lang.reflect.Method;
 7 import java.util.ArrayList;
 8 import java.util.List;
 9 
10 /**
11  * @Description //實體對象屬性比較工具類
12  * @Author yangli
13  **/
14 @Slf4j
15 public class BeanChangeUtils {
16 
17     /**
18      * @Description: 比較對象下同一屬性的修改
19      * @param oldBean
20      * @param newBean
21      * @Return: java.util.List<entity.ModifyInfo>
22      * @Author: yangli
23      **/
24     public static List<ModifyInfo> contrastObj(Object oldBean, Object newBean) {
25         List<ModifyInfo> modifyInfoList = new ArrayList<>();
26         try {
27             // 通過反射獲取類的類類型及字段屬性
28             Class clazzOld = oldBean.getClass();
29             Class clazzNew = newBean.getClass();
30 
31             Field[] fields = clazzOld.getDeclaredFields();
32             for (Field field : fields) {
33                 // 檢查屬性上有無 自定義對比 注解 -> 無則直接跳過
34                 BeanContrast contrastAnnotation = field.getAnnotation(BeanContrast.class);
35                 if (contrastAnnotation == null) {
36                     continue;
37                 }
38 
39                 //獲取字段名描述
40                 String modifyField = contrastAnnotation.fieldDesc();
41 
42                 PropertyDescriptor pdOld = new PropertyDescriptor(field.getName(), clazzOld);
43                 PropertyDescriptor pdNew = new PropertyDescriptor(field.getName(), clazzNew);
44                 // 獲取對應屬性值
45                 Method getMethodOld = pdOld.getReadMethod();
46                 Object o1 = getMethodOld.invoke(oldBean);
47                 Method getMethodNew = pdNew.getReadMethod();
48                 Object o2 = getMethodNew.invoke(newBean);
49                 if (o1 == null && o2 == null) {
50                     continue;
51                 }
52 
53                 if(o1 == null){
54                     // o2不為null的情況
55                     if(StringUtils.isNotBlank(o2.toString())) {
56                         ModifyInfo modifyInfo = ModifyInfo.builder()
57                                 .modifyField(modifyField)
58                                 .beforeModify("")
59                                 .afterModify(o2.toString())
60                                 .build();
61                         modifyInfoList.add(modifyInfo);
62                     }
63                 } else {
64                     // O1不為null
65                     if(o2 == null ) {
66                         // o2為null的情況
67                         if (StringUtils.isNotBlank(o1.toString())) {
68                             ModifyInfo modifyInfo = ModifyInfo.builder()
69                                     .modifyField(modifyField)
70                                     .beforeModify(o1.toString())
71                                     .afterModify("")
72                                     .build();
73                             modifyInfoList.add(modifyInfo);
74                         }
75                     } else {
76                         // o2 不為null的情況
77                         if ((StringUtils.isNotBlank(o1.toString()) || StringUtils.isNotBlank(o2.toString()))
78                                 && !o1.toString().equals(o2.toString())) {
79                             ModifyInfo modifyInfo = ModifyInfo.builder()
80                                     .modifyField(modifyField)
81                                     .beforeModify(o1.toString())
82                                     .afterModify(o2.toString())
83                                     .build();
84                             modifyInfoList.add(modifyInfo);
85                         }
86                     }
87                 }
88             }
89         } catch (Exception e) {
90             log.error("對比實體變更信息失敗:", e);
91             throw new Exception("系統異常");
92         }
93 
94         return modifyInfoList;
95     }
96 
97 }

四、打完收功~


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM