实现记录操作日志的功能,用自定义元注解能灵活控制不需要比较哪些字段、字段名称如何显示等思路,代码如下:
1.定义自定义元注释
/** * @author huangzhihua * @date 2020/11/9 */ @Documented @Target({ElementType.TYPE, ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) @Inherited public @interface Description { public String name() default ""; public boolean ignore() default false; }
2.在java对应实体类中添加注释
import com.example.demo.log.Description; import lombok.Builder; import lombok.Data; /** * @author huangzhihua * @date 2020/11/7 */ @Data @Builder public class UserVO { @Description(name = "id", ignore = true) public long id; @Description(name = "姓名") private String name; @Description(name = "年龄") private Integer age; @Description(name = "描述") private String desc; }
3.基于反射实现的对象比较
/** * @author huangzhihua * @date 2020/11/7 */ public class CompareUtils<T> { /** * 对象比较器 * * @param oldBean * @param newBean * @return */ public String contrastObj(Object oldBean, Object newBean) { String str = ""; //if (oldBean instanceof SysConfServer && newBean instanceof SysConfServer) { T pojo1 = (T) oldBean; T pojo2 = (T) newBean; try { Class clazz = pojo1.getClass(); Field[] fields = pojo1.getClass().getDeclaredFields(); int i = 1; for (Field field : fields) { //获取字段注释信息 Description description = (Description) field.getAnnotation(Description.class); // 注解中忽略的字段 if (description == null || description.ignore()) { continue; } if ("serialVersionUID".equals(field.getName())) { continue; } PropertyDescriptor pd = new PropertyDescriptor(field.getName(), clazz); Method getMethod = pd.getReadMethod(); Object o1 = getMethod.invoke(pojo1); Object o2 = getMethod.invoke(pojo2); if (o1 == null || o2 == null) { continue; } if (!o1.toString().equals(o2.toString())) { if (i != 1) { str += "; "; } str += i + "、字段名称:" + description.name() + ",旧值:" + o1 + ",新值:" + o2; i++; } } } catch (Exception e) { e.printStackTrace(); } // } return str; }
4.测试运行
UserVO user1 = UserVO.builder().name("jack").age(19).desc("my name").build(); UserVO user2 = UserVO.builder().name("rose").age(18).desc("my name").build();
@Test void test(){ System.out.println(new CompareUtils<UserVO>().contrastObj(user1,user2)); }