将 setter 调用到用 AspectJ 注释的字段
Call a setter to a field which is annotated with AspectJ
在这种情况下,我想拦截对一个用 MyAnnotation 注释的字段的所有分配。如果它在通过反射分配值时有效,那就更好了。
这是我尝试过的方法,但它没有 运行,我认为可能还有其他问题:
public privileged aspect MyAnnotationAspect {
pointcut hasAnnotation(MyAnnotation annotation) : @annotation(annotation);
pointcut methodExecution() : execution(* *(..));
Object around(MyAnnotation annotation) : set(String word) && methodExecution() && hasAnnotation(annotation) {
Object result = null;
try {
result = proceed(annotation, "new"); //Just to try I want to assign "new" instead of the variable word
} catch (Throwable ex) {
throw new RuntimeException(ex);
}
return result;
}
}
它说该方法的参数太多。谁能帮我?谢谢!
编辑
现在抛出 "Warning:(10, 0) ajc: advice defined in aspects.AnnotationAspect has not been applied [Xlint:adviceDidNotMatch]"
这是我的方面:
public aspect AnnotationAspect {
pointcut hasAnnotation(Annotation annotation) : @annotation(annotation);
Object around(Annotation annotation, String word) : hasAnnotation(annotation) && set(String *) && args(word) {
Object result = null;
System.out.println(thisJoinPoint);
try {
result = proceed(annotation, "intercepted");
} catch (RuntimeException ex) {
throw ex;
}
return result;
}
}
这是注释:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Annotation {
}
我有一个假人来测试它:
class DummyEntity{
@Annotation
var name: String =_
def setName(n: String): Unit ={
name = n
}
}
这是我正在测试的测试:
public class AnnotationAspectTest {
private DummyEntity dummyEntity;
@Before
public void setUp(){
dummyEntity = new DummyEntity();
}
@Test
public void testing(){
dummyEntity.setName("newName");
Assert.assertEquals("intercepted", dummyEntity.name());
}
}
methodExecution()
在这里适得其反,因为你不想捕获方法执行,而是字段写访问。因为 set(..) && execution(..)
是互斥的,所以这没有逻辑意义。
此外,您需要通过args()
将分配的值绑定到参数,以便能够对其进行修改。
package de.scrum_master.aspect;
import de.scrum_master.app.MyAnnotation;
public aspect MyAnnotationAspect {
Object around(MyAnnotation annotation, String word) :
@annotation(annotation) && set(String *) && args(word)
{
System.out.println(thisJoinPoint);
Object result = null;
try {
result = proceed(annotation, "altered value");
} catch (Throwable ex) {
throw new RuntimeException(ex);
}
return result;
}
}
在这种情况下,我想拦截对一个用 MyAnnotation 注释的字段的所有分配。如果它在通过反射分配值时有效,那就更好了。 这是我尝试过的方法,但它没有 运行,我认为可能还有其他问题:
public privileged aspect MyAnnotationAspect {
pointcut hasAnnotation(MyAnnotation annotation) : @annotation(annotation);
pointcut methodExecution() : execution(* *(..));
Object around(MyAnnotation annotation) : set(String word) && methodExecution() && hasAnnotation(annotation) {
Object result = null;
try {
result = proceed(annotation, "new"); //Just to try I want to assign "new" instead of the variable word
} catch (Throwable ex) {
throw new RuntimeException(ex);
}
return result;
}
}
它说该方法的参数太多。谁能帮我?谢谢!
编辑
现在抛出 "Warning:(10, 0) ajc: advice defined in aspects.AnnotationAspect has not been applied [Xlint:adviceDidNotMatch]"
这是我的方面:
public aspect AnnotationAspect {
pointcut hasAnnotation(Annotation annotation) : @annotation(annotation);
Object around(Annotation annotation, String word) : hasAnnotation(annotation) && set(String *) && args(word) {
Object result = null;
System.out.println(thisJoinPoint);
try {
result = proceed(annotation, "intercepted");
} catch (RuntimeException ex) {
throw ex;
}
return result;
}
}
这是注释:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Annotation {
}
我有一个假人来测试它:
class DummyEntity{
@Annotation
var name: String =_
def setName(n: String): Unit ={
name = n
}
}
这是我正在测试的测试:
public class AnnotationAspectTest {
private DummyEntity dummyEntity;
@Before
public void setUp(){
dummyEntity = new DummyEntity();
}
@Test
public void testing(){
dummyEntity.setName("newName");
Assert.assertEquals("intercepted", dummyEntity.name());
}
}
methodExecution()
在这里适得其反,因为你不想捕获方法执行,而是字段写访问。因为 set(..) && execution(..)
是互斥的,所以这没有逻辑意义。
此外,您需要通过args()
将分配的值绑定到参数,以便能够对其进行修改。
package de.scrum_master.aspect;
import de.scrum_master.app.MyAnnotation;
public aspect MyAnnotationAspect {
Object around(MyAnnotation annotation, String word) :
@annotation(annotation) && set(String *) && args(word)
{
System.out.println(thisJoinPoint);
Object result = null;
try {
result = proceed(annotation, "altered value");
} catch (Throwable ex) {
throw new RuntimeException(ex);
}
return result;
}
}