2

我的确切要求是将旧对象和新对象的值一起记录。例如,如果以前用户的名称是“AAA”并且有人将名称更改为“CCC”而不是在服务层中,我需要像这样记录“用户名从 AAA 更改为 CCC,日期为 2013 年 9 月 10 日”。请在spring框架中提供一些解决方案。

4

2 回答 2

1

据我所知,Spring 不提供任何此类功能。

但是,您想要的很容易实现:使用Reflection,或者使用BeanUtils,它无论如何都在内部使用Reflection 。使用其中任何一个,您都可以迭代对象的属性并创建一个Map或包含必要细节的东西。看看这两个答案:

用于在两个 bean 中生成字段差异的通用算法

找出两个 java-beans-for-version-tracking 之间的差异

或者,有一个名为java-object-diff的库可以为您完成。它还支持深度对象比较,并为您处理大量复杂性。

此外,您可能对BeanUtils 的这个 JIRA 问题感兴趣。请参阅评论部分。

于 2013-08-30T09:42:39.293 回答
1

可以使用Spring AOP,拦截bean的setter,记录属性变化,基本思路在这里

class B1 {
    String name = "xxx";
    public void setName(String name) {
        this.name = name;
    }
    public String getName() {
        return name;
    }
}

@Aspect
class A1 {
    @Before("execution(void test.B1.set*(*))")
    public void before(JoinPoint jp) throws Exception {
        String prop = jp.getSignature().getName().substring(3);
        Object target = jp.getTarget();
        Object before = target.getClass().getMethod("get" + prop).invoke(target);
        Object now = jp.getArgs()[0];
        System.out.println(prop + " changed from " + before + " to " + now);
    }
}

public class Test1 {

    public static void main(String[] args) throws Exception {
        ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("test1.xml");
        B1 b1 = ctx.getBean(B1.class);
        b1.setName("yyy");
    }
}

这打印

Name changed from xxx to yyy

测试1.xml

...
    <context:annotation-config />
    <aop:aspectj-autoproxy />
    <bean class="test.B1" />
    <bean class="test.A1" />
...
于 2013-08-30T10:00:37.127 回答