Affects: spring-aop:5.0.9.RELEASE, spring-boot-starter-aop:2.0.5.RELEASE
public interface FooService {
@MyAnnotation
void hello();
}
public class FooServiceImpl implements FooService {
void hello();
}
public class MyAspect {
@Pointcut("@annotation(MyAnnotation")
public void myPointcut() {
}
@Around("myPointcut()")
public Object around(ProceedingJoinPoint pjp) throws Throwable {
...
}
}
@Configuration
public class MyAopConfiguration {
@Bean
public MyAspect myAspect () {
return new MyAspect();
}
}
Using spring-aop like the code above, it doesn't work, around(ProceedingJoinPoint pjp) never executes.
If put the @MyAnnotation on the implemented method of FooServiceImpl, it works.
public interface FooService {
void hello();
}
public class FooServiceImpl implements FooService {
@MyAnnotation
void hello();
}
Learned from two questions in Stack Overflow:
According to the Java 5 specification, non-type annotations are not inherited, and annotations on types are only inherited if they have the @Inherited meta-annotation.
It's seems that it's impossible in spring-aop.
I tried the code without spring-aop, only using aspectjweaver 1.7.4, and adding an aop.xml in resources/META-INF:
<?xml version="1.0" encoding="UTF-8"?>
<aspectj>
<aspects>
<aspect name="com.xxx.MyAspect"/>
</aspects>
<weaver options="-verbose -showWeaveInfo -Xset:weaveJavaxPackages=true" />
</aspectj>
and adding JVM parameter:
-javaagent:xxx/aspectjweaver-1.7.4.jar
It works no matter the @MyAnnotation is on the interface or class. And then in around(ProceedingJoinPoint pjp), I can get the @MyAnnotation with the API of pjp, like this:
MethodSignature signature = (MethodSignature)joinPoint.getSignature();
Class<?> targetClass = pjp.getTarget().getClass();
Method method = targetClass.getDeclaredMethod(signature.getName(), signature.getMethod().getParameterTypes());
MyAnnotation myAnnotation = method.getAnnotation(MyAnnotation.class);
or
Class<?>[] interfaces = targetClass.getInterfaces();
for (Class<?> anInterface : interfaces) {
Method method = targetClass.getDeclaredMethod(signature.getName(),
signature.getMethod().getParameterTypes());
MyAnnotation myAnnotation = method.getAnnotation(MyAnnotation.class);
}
So I think spring-aop may also have way to solve this problem, since it's a common use case for users to add annotation on the method of interface.
Something in AopUtils#getMostSpecificMethod, AspectJExpressionPointcut#getShadowMatch(Method targetMethod, Method originalMethod) may be about, I'm not sure.
Could you please give some help?
Affects: spring-aop:5.0.9.RELEASE, spring-boot-starter-aop:2.0.5.RELEASE
Using
spring-aoplike the code above, it doesn't work,around(ProceedingJoinPoint pjp)never executes.If put the
@MyAnnotationon the implemented method ofFooServiceImpl, it works.Learned from two questions in Stack Overflow:
According to the Java 5 specification, non-type annotations are not inherited, and annotations on types are only inherited if they have the
@Inheritedmeta-annotation.It's seems that it's impossible in
spring-aop.I tried the code without
spring-aop, only usingaspectjweaver1.7.4, and adding anaop.xmlinresources/META-INF:and adding JVM parameter:
-javaagent:xxx/aspectjweaver-1.7.4.jarIt works no matter the
@MyAnnotationis on the interface or class. And then inaround(ProceedingJoinPoint pjp), I can get the@MyAnnotationwith the API of pjp, like this:or
So I think
spring-aopmay also have way to solve this problem, since it's a common use case for users to add annotation on the method of interface.Something in
AopUtils#getMostSpecificMethod,AspectJExpressionPointcut#getShadowMatch(Method targetMethod, Method originalMethod)may be about, I'm not sure.Could you please give some help?