Aspecj cannot intercept method annotations on an interface
Aspecj can’t intercept the method annotation on the interface, it can only act on the method of the implementation class. At this time, it needs to use methodinterceptor
to implement.
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface AopTest {
}
Interface
public interface TestAOPI {
@AopTest
public String test();
}
Implementation class 1
@Service
public class TestAOPService implements TestAOPI{
@Override
public String test() {
return "service";
}
}
Implementation class 2
@Service
public class TestAOPService2 implements TestAOPI{
@AopTest
@Override
public String test() {
return "service";
}
}
Aspecj (partially valid)
If and only if the @ aoptest
annotation is added to the method of the implementation class, it will take effect (implementation class 2), but implementation class 1 will not
@Aspect
@Configuration
public class AopTestAspect {
/**
* Identifies the method annotated with OperationLog
*/
@Pointcut("@annotation(com.example.demo1.config.AopTest)")
public void methodHasAopTestAnnotation() {
}
@Around("methodHasAopTestAnnotation()")
public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("aop!!!");
return joinPoint.proceed();
}
}
Solution
It needs to be changed to the following way by manual
@Configuration
public class AopTestConfiguration {
@Bean
public Advisor methodPointcutAdvisor() {
AopTestMethodPointcutAdvisor advisor = new AopTestMethodPointcutAdvisor();
advisor.setAdvice(new AopTestInterceptor());
return advisor;
}
class AopTestInterceptor implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
String name = invocation.getMethod().getName();
System.out.println("==============" + name + " before ================");
Object result = invocation.proceed();
System.out.println("==============" + name + " after ================");
return result;
}
}
public class AopTestMethodPointcutAdvisor extends StaticMethodMatcherPointcutAdvisor {
@Override
public boolean matches(Method method, Class<?> targetClass) {
// Implementing a class method with a target annotation on it
if(method.isAnnotationPresent(AopTest.class)){
return true;
}
// The method has a corresponding interface method and the interface method is annotated
Class<?>[] interfaces = method.getDeclaringClass().getInterfaces();
for (int i = 0; i < interfaces.length; i++) {
Method[] methods = interfaces[i].getMethods();
for (int j = 0; j < methods.length; j++) {
if(methods[j].getName().equals(method.getName())){
return methods[j].isAnnotationPresent(AopTest.class);
}
}
}
return false;
}
}
}