超类中带有自定义注释的 AOP 不起作用

use*_*015 2 java spring aspectj spring-aop

自定义注释

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface CustomAnnotation {
}
Run Code Online (Sandbox Code Playgroud)

自定义注释处理程序

@Aspect
public class TestAspectHandler {
    @Around("execution(@com.test.project.annotaion.CustomAnnotation * *(..)) && @annotation(customAnnotation)")
    public Object testAnnotation(ProceedingJoinPoint joinPoint, CustomAnnotation customAnnotation) throws Throwable {
        System.out.println("TEST");
        return result;
    }
}
Run Code Online (Sandbox Code Playgroud)

超级班

public class AbstractDAO {
     @CustomAnnotation
     protected int selectOne(Object params){
          // .... something
     }
}
Run Code Online (Sandbox Code Playgroud)

子类

public class SubDAO extends AbstractDAO {
    public int selectSub(Object params) {
         return selectOne(params);
    }
}
Run Code Online (Sandbox Code Playgroud)

子类SubDAO调用 SuperClass 方法selectOneTestAspectHandler.class不调用testAnnotation(...)

当我转到@CustomAnnotation子类selectSub(..)方法 AspectHandler 可以得到joinPoint

如何在超类保护方法中使用自定义注释?


added

改变 TestAspectHandler.testAnnotation(...) method

@Around("execution(* *(..)) && @annotation(customAnnotation)")
public Object testAnnotation(ProceedingJoinPoint joinPoint, CustomAnnotation customAnnotation) throws Throwable {
            System.out.println("TEST");
            return result;
}
Run Code Online (Sandbox Code Playgroud)

但仍然不起作用

所以我SubDAO在代码下改变我的喜好

public class SubDAO extends AbstractDAO {
    @Autowired
    private AbstractDAO abstractDAO;
    public int selectSub(Object params) {
         return abstractDAO.selectOne(params);
    }
}
Run Code Online (Sandbox Code Playgroud)

这不是完美的解决方案,但它有效


  • 案例1:从子类方法调用超类方法不起作用
  • 案例 2:使超类实例和从实例调用工作

kri*_*aex 6

首先,我希望你的 DAO 类是真正的 Spring 组件,否则 Spring AOP 找不到它们,只有 AspectJ 可以。

但在其核心,这不是 Spring 或 AspectJ 问题。在 Java 中,注释

  • 接口,
  • 其他注释或
  • 方法

永远不会被继承

  • 实现类,
  • 使用带注释的类或
  • 覆盖方法。

注解继承仅适用于从类到子类的类,但前提是超类中使用的注解类型带有元注解@Inherited,请参阅JDK JavaDoc

因为我之前已经多次回答过这个问题,所以我刚刚在用 AspectJ 模拟接口和方法的注释继承中记录了这个问题和解决方法


更新:抱歉,我只是更彻底地检查了您的代码。您没有覆盖超类的带注释的方法(至少您的代码没有显示您覆盖了 method selectOne),因此我上面描述的内容不适用于此处。你的方面应该有效。但是,也许你只需要在完全限定类名称的拼写错误@com.test.project.annotaion.CustomAnnotation:将annotaion(注意错字!)包的名字应该很可能宁可annotation。正如我在第一句话中所说:DAO 必须是 Spring@Component的。

顺便说一句:您可以完全避免切入点的那部分,因为您已经将注释绑定到参数。只需使用

@Around("execution(* *(..)) && @annotation(customAnnotation)")
Run Code Online (Sandbox Code Playgroud)