简体   繁体   English

Spring AOP不拦截Spring容器中的方法

[英]Spring AOP does not intercept methods within Spring's container

I am new to Spring AOP. 我是Spring AOP的新手。
Using annotation based Spring configuration: 使用基于注释的Spring配置:

@Configuration
@EnableAspectJAutoProxy(proxyTargetClass=true)
@ComponentScan({"sk.lkrnac"})

Aspect: 方面:

@Aspect
@Component
public class TestAspect {
    @Before("execution(* *(..))")
    public void logJoinPoint(JoinPoint joinPoint){
        ....
    }

}

Spring compoment: 弹簧组件:

package sk.lkrnac.testaop;

@Component
public class TestComponent{
    @PostConstruct
    public void init(){
        testMethod();
    }

    public void testMethod() {
        return;
    }
}

How can I intercept all public methods that are called by Spring framework itself? 如何拦截Spring框架本身调用的所有公共方法? (eg TestComponent.init() during creation of the TestComponent instance by Spring) Currently I am able to intercept only TestComponent.testMethod() by invoking: (例如,Spring创建TestComponent实例时的TestComponent.testMethod() )目前我只能通过调用来拦截TestComponent.testMethod()

TestComponent testComponent = springContext.getBean(TestComponent.class);
testComponent.testMethod();

This is a common issue you run into with Spring AOP. 这是Spring AOP遇到的常见问题。 Spring accomplishes AOP by proxying advised classes. Spring通过代理建议的类来完成AOP。 In your case, your TestComponent instances will be wrapped in a run-time proxy class that provides the "hooks" for any aspect advice to be applied. 在您的情况下,您的TestComponent实例将包装在运行时代理类中,该类为要应用的任何方面建议提供“挂钩”。 This works very well when methods are called from outside the class, but as you have discovered it doesn't work on internal calls. 当从类外部调用方法时,这非常有效,但是正如您所发现的那样,它不适用于内部调用。 The reason is that internal calls will not pass the proxy barrier, thus will not trigger the aspect. 原因是内部调用不会通过代理屏障,因此不会触发方面。

There are primarily two ways around this. 主要有两种方法。 One is to fetch an instance of the (proxied) bean from the context. 一种是从上下文中获取(代理)bean的实例。 This is what you have already tried with success. 这是你已经尝试过的成功。

The other way is to use something called load-time weaving. 另一种方法是使用称为加载时编织的东西。 When using this, AOP advices are added to a class ("weaved" into it) by a custom class-loader by injecting byte-code into the class definition. 使用它时,AOP建议通过将字节代码注入类定义,由自定义类加载器添加到类(“编织”到其中)。 The Spring documentation has more on this. Spring文档对此有更多了解。

There is a third way, which is called "compile time weaving". 还有第三种方法,称为“编译时编织”。 In this scenario, your AOP advices are statically weaved into each advised class when you compile it. 在这种情况下,在编译时,您的AOP建议会静态编织到每个建议的类中。

您无法在没有任何明确方法的情况下拦截init() ,有关详细信息,请参阅SpringSource Jira

您也可以尝试通过自己通过代理对象从init()调用内部testMethod(),如Don在https://stackoverflow.com/a/5786362/6786382中所述

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM