• 操作审计记录


    实现记录操作日志的功能,用自定义元注解能灵活控制不需要比较哪些字段、字段名称如何显示等思路,代码如下:

    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));
        }

    Java对象比较器,详细记录对象前后变化的方法

    使用java反射和AOP对比两个对象的属性来实现修改操作日志记录功能

  • 相关阅读:
    ZJOI2017 Day3 滚粗记
    ZJOI2017 Day2
    bzoj4245 [ONTAK2015]OR-XOR (贪心)
    bzoj4631 踩气球 (树状数组+线段树)
    bzoj5219 [Lydsy2017省队十连测]最长路径 (DP)
    bzoj5216 [Lydsy2017省队十连测]公路建设 (线段树)
    bzoj2754 [SCOI2012]喵星球上的点名 (后缀数组+树状数组)
    bzoj2342 [Shoi2011]双倍回文 (manacher)
    bzoj4657 tower (最小割)
    bzoj2064 分裂 (状压dp)
  • 原文地址:https://www.cnblogs.com/edda/p/13947655.html
Copyright © 2020-2023  润新知