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 }

四、打完收功~

posted @ 2020-09-27 17:04  时の封印  阅读(1655)  评论(0编辑  收藏  举报