Reputation: 4303
So I've defined pointcuts for all methods and all classes of a particular annotation... what I want to do is retrieve the annotation value on every method call. Here is what I have so far
@Aspect
public class MyAspect {
@Pointcut("execution(* my.stuff..*(..))")
private void allMethods(){}
@Pointcut("within(@my.stuff.MyAnnotation*)")
private void myAnnotations(){}
@Pointcut("allMethods() && myAnnotations()")
private void myAnnotatedClassMethods(){}
@Before("myAnnotatedClassMethods()")
private void beforeMyAnnotatedClassMethods(){
System.out.println("my annotated class method detected.");
// I'd like to be able to access my class level annotation's value here.
}
}
Upvotes: 1
Views: 224
Reputation: 279970
Yes, you can have Spring AOP supply the value of the annotation annotating your target object's class.
You'll have to use the binding forms documented in the specification and propagate an argument across your @Pointcut
methods.
For example
@Pointcut("execution(* my.stuff..*(..))")
private void allMethods() {
}
@Pointcut("@within(myAnnotation)")
private void myAnnotations(MyAnnotation myAnnotation) {
}
@Pointcut("allMethods() && myAnnotations(myAnnotation)")
private void myAnnotatedClassMethods(MyAnnotation myAnnotation) {
}
@Before("myAnnotatedClassMethods(myAnnotation)")
private void beforeMyAnnotatedClassMethods(MyAnnotation myAnnotation){
System.out.println("my annotated class method detected: " + myAnnotation);
}
Spring, starting from the myAnnotations
pointcut, will match the name given in @within
with a method parameter and use that to determine the annotation type. That is then propagated down to the beforeMyAnnotatedClassMethods
advice through the myAnnotatedClassMethods
pointcut.
The Spring AOP stack will then lookup the annotation value before invoking your @Before
method and pass it as an argument.
An alternative, if you don't like the solution above, is to simply provide a JoinPoint
parameter in your advice method. You can use it to resolve the target
instance with getTarget
and use that value to get the class annotation. For example,
@Before("myAnnotatedClassMethods()")
private void beforeMyAnnotatedClassMethods(JoinPoint joinPoint) {
System.out.println("my annotated class method detected: " + joinPoint.getTarget().getClass().getAnnotation(MyAnnotation.class));
}
I'm unsure how this will behave if the target is further wrapped in other proxies. The annotation might be "hidden" behind proxy classes. Use it carefully.
Upvotes: 1