Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/354.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 超类中带有自定义注释的AOP不';行不通_Java_Spring_Aspectj_Spring Aop - Fatal编程技术网

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不是。)