Reputation: 101
I have service code like this:
@Component
public class MyService implements com.xyz.WithSession {
public void someMethodWhichDoesNotNeedAutorization() {
// code S1
}
@com.xyz.WithAuthorization
public void someMethodWhichNeedAutorization() {
// code S2
}
}
and aspect like this:
@Aspect
public class MyAspect {
@Before("target(com.xyz.WithSession)")
public void adviceBeforeEveryMethodFromClassImplementingWithSession() {
// code A1
}
@Before("target(com.xyz.WithSession) && @annotation(com.xyz.WithAuthorization)")
public void adviceBeforeWithAuthorizationMethodFromClassImplementingWithSession() {
// code A2
}
Annotation looks like:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface WithAuthorization{
}
What am I doing wrong?
Code is written in Java 7 with Spring 3.1.3.
I've tried another way. I use 'Around' advice instead of 'Before' and 'After' to have access to ProceedingJoinPoint. In this advice I check with reflection whether method has annotation 'com.xyz.WithAuthorization' or not:
private boolean isAnnotated(ProceedingJoinPoint proceedingJoinPoint) {
MethodSignature signature = (MethodSignature) proceedingJoinPoint.getSignature();
return signature.getMethod().isAnnotationPresent(com.xyz.WithAuthorization);
}
My annotation has '@Retention(RetentionPolicy.RUNTIME)' but I see in debugger that annotation is missing on runtime in the method signature. So the problem still exists.
Upvotes: 4
Views: 8344
Reputation: 7889
Your second pointcut
@Before("target(com.xyz.WithSession) && @annotation(com.xyz.WithAuthorization)")
fails in two ways. First the
target(com.xyz.WithSession)
matches only classes, not methods. So like @Xstian pointed out you should use something along the lines of
execution(* com.whatever.MyService.*(..))
to match all methods inside the MyService class.
Second problem is the
@annotation(com.xyz.WithAuthorization)
where the argument should be name that matches the argument name in the advice. So you use @annotation(someArgumentName)
and then have com.xyz.WithAuthorization someArgumentName
as your advice methods argument.
Upvotes: 2
Reputation: 8272
In Spring Reference at this link
e.g. in Spring reference
@Before("com.xyz.lib.Pointcuts.anyPublicMethod() && @annotation(auditable)")
public void audit(Auditable auditable) {
AuditCode code = auditable.value();
// ...
}
the execution of any method defined by the AccountService interface:
execution(* com.xyz.service.AccountService.*(..))
any join point (method execution only in Spring AOP) where the executing method has an @Transactional annotation:
@annotation(org.springframework.transaction.annotation.Transactional)
I suggest you to use...
@Before("execution(* com.xyz.WithSession.*(..)) && @annotation(authorization)")
public void adviceBeforeWithAuthorizationMethodFromClassImplementingWithSession(WithAuthorization authorization) {
// code A2
}
Upvotes: 4
Reputation: 67317
Probably your annotation does not have runtime retention:
@Retention(RetentionPolicy.RUNTIME)
public @interface WithAuthorization {}
Upvotes: 1