调用setter到一个用AspectJ注释的字段 [英] Call a setter to a field which is annotated with AspectJ
问题描述
在这种情况下,我想拦截对所有使用MyAnnotation注释的字段的分配.如果它有效,则为反射赋值时会更好. 这是我尝试过的方法,但是没有运行,我认为还有其他问题:
I want to intercept all assignments to a field which is annotated with MyAnnotation in this case. If it works when the value is assigned with reflction is much better. This is what I tried, but it does not run, and I think that something else might be wrong:
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;
}
}
它表示该方法进行的参数过多.谁能帮我?谢谢!
It says that are too many arguments for the method proceed. Can anyone help me? Thank you!
编辑
现在,它引发警告:(10,0)ajc:方面中定义的建议.尚未应用[Xlint:adviceDidNotMatch] AnnotationAspect"
Now it throws "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 {
}
我有一个假人来测试它:
I have a dummy in order to test it:
class DummyEntity{
@Annotation
var name: String =_
def setName(n: String): Unit ={
name = n
}
}
这是我正在测试的测试:
And this is the test where I'm testing it:
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(..)
是互斥的,所以这没有逻辑意义.
The methodExecution()
is counter-productive here because you do not want to capture method executions, but field write access. Because set(..) && execution(..)
are mutually exclusive, this makes no logical sense.
此外,您需要通过args()
将分配的值绑定到参数,以便能够对其进行修改.
Furthermore, you need to bind the assigned value to a parameter via args()
in order to be able to modify it.
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;
}
}
这篇关于调用setter到一个用AspectJ注释的字段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!