操作审计记录

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

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 += ";\n";
                    }
                    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对比两个对象的属性来实现修改操作日志记录功能

posted @   edda_huang  阅读(162)  评论(0编辑  收藏  举报
编辑推荐:
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
点击右上角即可分享
微信分享提示

目录导航