问题描述
亲爱的所有我使用Spring AOP(v4)和AspectJ加载时间编织器。
Dear all I am curently using Spring AOP (v4) and AspectJ with load-time-weaver.
我正在寻找一种添加脏标志的方法机制进入我的豆子。因此,我在使用AOP调用方法之前调用一个方法来调用我的bean。我已经实现了这一点,但是如何在修改之前访问旧的字段值?或者有没有办法获取字段名称,以便我可以在调用setter之前调用getter?
I am looking currently for a way to add a dirty flag mechanism into my beans. Therefore I I though of using AOP to call a method before a setter of my beans get called. This I achieved already, but how can I access the old field value beforeit get modified? Or is there a way to get the field name so I can call the getter before the setter get called?
有人可以在这里提供一些示例切入点/建议如何看起来想把它作为参数传递?
Can anybody provide me here some example how the pointcut/advice has to look like to get it a passed as arguments?
@Aspect
public class MyAspect {
@Before("execution(* foo.*.set*(..))")
public void beforeSetterCalled(JoinPoint joinPoint){
System.out.println("beforeSetter");
}
}
不幸的是,Spring AOP似乎不支持 set()field-pointcut construct,这是正确的吗?或者在某种程度上存在使用它?
Unfortunately it seems that Spring AOP does not support the "set()" field-pointcut construct, is this correct? OR exists someway to use this?
感谢您的帮助。
推荐答案
我建议将完整的AspectJ与 set()
切入点结合使用,以获得有效的解决方案。但如果你不介意有一个涉及反思的缓慢,丑陋的解决方案,你也可以这样做:
I would recommend to use full AspectJ in combination with a set()
pointcut in order to get an efficient solution. But if you do not mind having a slow, ugly solution involving reflection you can also do something like this:
package de.scrum_master.app;
public class Person {
private int id;
private String firstName;
private String lastName;
public Person(int id, String firstName, String lastName) {
this.id = id;
this.firstName = firstName;
this.lastName = lastName;
}
public int getId() { return id; }
public String getFirstName() { return firstName; }
public String getLastName() { return lastName; }
public void setId(int id) { this.id = id; }
public void setFirstName(String firstName) { this.firstName = firstName; }
public void setLastName(String lastName) { this.lastName = lastName; }
@Override
public String toString() { return "Person [" + id + ", " + firstName + " " + lastName + "]"; }
public static void main(String[] args) {
Person albert = new Person(1, "Albert", "Camus");
Person audrey = new Person(2, "Audrey", "Hepburn");
System.out.println(albert);
System.out.println(audrey);
System.out.println();
albert.setId(8);
albert.setLastName("Einstein");
audrey.setId(9);
audrey.setLastName("Tautou");
System.out.println();
System.out.println(albert);
System.out.println(audrey);
}
}
package de.scrum_master.aspect;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.SoftException;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
@Aspect
public class SetterInterceptor {
@Before("execution(* set*(*)) && target(instance) && args(newValue)")
public void beforeSetterCalled(JoinPoint thisJoinPoint, Object instance, Object newValue) {
String methodName = thisJoinPoint.getSignature().getName();
try {
System.out.println(
methodName.substring(3) + ": " +
instance
.getClass()
.getMethod(methodName.replaceFirst("set", "get"))
.invoke(instance) +
" -> " + newValue
);
} catch (Exception e) {
throw new SoftException(e);
}
}
}
控制台日志:
Person [1, Albert Camus]
Person [2, Audrey Hepburn]
Id: 1 -> 8
LastName: Camus -> Einstein
Id: 2 -> 9
LastName: Hepburn -> Tautou
Person [8, Albert Einstein]
Person [9, Audrey Tautou]
这篇关于Spring AOP - 在调用setter之前获取旧字段值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!