AspecJ 无法拦截接口上的方法加注解
AspecJ 无法拦截接口上的方法加注解,只能作用在实现类的方法上,这时需要利用 MethodInterceptor
来实现。
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface AopTest {
}
接口
public interface TestAOPI {
@AopTest
public String test();
}
实现类 1
@Service
public class TestAOPService implements TestAOPI{
@Override
public String test() {
return "service";
}
}
实现类 2
@Service
public class TestAOPService2 implements TestAOPI{
@AopTest
@Override
public String test() {
return "service";
}
}
AspecJ写法(部分有效)
当且仅当 @AopTest
注解加在实现类的方法上时才会生效(实现类2),而实现类1 不生效
@Aspect
@Configuration
public class AopTestAspect {
/**
* 标识加了 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();
}
}
解决方案
需要改为以下方式,通过手动
@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) {
// 实现类方法上含有目标注解
if(method.isAnnotationPresent(AopTest.class)){
return true;
}
// 该方法有对应的接口方法,且接口方法上加了注解
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;
}
}
}