Aspecj cannot intercept method annotations on an interface

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;
        }
    }
}

Read More: