Java 超类中带有自定义注释的AOP不';行不通
自定义注释Java 超类中带有自定义注释的AOP不';行不通,java,spring,aspectj,spring-aop,Java,Spring,Aspectj,Spring Aop,自定义注释 @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface CustomAnnotation { } 自定义注释处理程序 @Aspect public class TestAspectHandler { @Around("execution(@com.test.project.annotaion.CustomAnnotation * *(..)) && @
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface CustomAnnotation {
}
自定义注释处理程序
@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;
}
}
超级级
public class AbstractDAO {
@CustomAnnotation
protected int selectOne(Object params){
// .... something
}
}
子类
public class SubDAO extends AbstractDAO {
public int selectSub(Object params) {
return selectOne(params);
}
}
子类SubDAO
调用超类方法selectOne
,但在TestSpectHandler.class
中不调用testAnnotation(…)
当我将@CustomAnnotation
移动到子类selectSub(..)
方法时,AspectHandler可以获得连接点
如何在超类保护方法中使用自定义注释
已添加
更改TestSpectHandler.testAnnotation(…)方法
@Around("execution(* *(..)) && @annotation(customAnnotation)")
public Object testAnnotation(ProceedingJoinPoint joinPoint, CustomAnnotation customAnnotation) throws Throwable {
System.out.println("TEST");
return result;
}
但还是不行
所以我把我的SubDAO
写在代码下面
public class SubDAO extends AbstractDAO {
@Autowired
private AbstractDAO abstractDAO;
public int selectSub(Object params) {
return abstractDAO.selectOne(params);
}
}
这不是一个完美的解决方案,但它确实有效
- 案例1:从子类方法调用超类方法不起作用
- 案例2:使超级类实例和实例调用工作
它的工作方式是,您的SpringBean代理(对SpringBean的每个引用实际上都是一个代理,委托给bean实例)为您的应用方面创建JDK Dynamoc代理(对于实现至少一个接口或CGLib代理的类)。因此,当调用selectSub方法时,它已经传递了Springbean委托,无法应用方面。
如果您想让它正常工作,您还必须注释子方法。首先,我希望您的DAO类是实际的Spring组件,否则Spring AOP找不到它们,只有AspectJ可以
但其核心不是Spring或AspectJ问题。在Java中,注释位于
- 接口
- 其他注释或
- 方法
永远不会被继承
- 实施课程,
- 使用带注释的注释或
- 重写方法
注释继承仅适用于从类到子类,但仅当超类中使用的注释类型具有元注释@Inherited
,请参阅
因为我以前已经回答过这个问题好几次了,所以我刚刚记录了这个问题,以及中的一个解决方法
更新:对不起,我刚刚更彻底地检查了您的代码。您没有覆盖超类的带注释的方法(至少您的代码没有显示您覆盖了方法selectOne
),因此我上面描述的内容在这里不适用。你的方面应该工作。但是,可能您只是在完全限定类名@com.test.project.annotation.CustomAnnotation
中有一个输入错误:注释
(注意输入错误!)包名应该是注释
。正如我在第一句话中所说的:DAO必须是Spring@Component
s
顺便说一下:您可以完全避免切入点的这一部分,因为您已经将注释绑定到参数。只用
@Around(“执行(**(..))&&&&@annotation(customAnnotation)”)
如果您已经阅读了我的答案,请同时阅读编辑/更新。现在有了新的信息。Spring AOP使用代理工作,只有对对象的方法调用通过代理,您正在进行内部方法调用,因此它不通过代理,因此AOP不被应用。其次,即使它将应用实际方法,也不会被调用,因为您的around方面打破了这一点。谢谢,但是around(“execution(**(..)&&&&@annotation(customAnnotation)”
不起作用:(阅读更新的问题然后您的Spring配置有问题。两个DAO都是Spring组件吗?正如我所说:Spring AOP在POJO上不起作用。是的,如果POJO不能使用@Autowiredy,两个DAO都是Spring组件。您的解决方法没有意义。为什么要使用继承,然后将父对象分配给成员?查找根本原因并解决问题!你说得对。但真的不知道为什么它不起作用:(.案例2是有效的,但案例1不是。)