項目中某些地方要求記錄信息變更日志,通過反射獲取屬性對比新舊信息的變化情況,然后記錄日志
一、創建實體類比較標志注解(只比較有注解的屬性)
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 }
四、打完收功~