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

时间:2013-01-01 14:52:34

标签: java spring aop

我是Spring AOP的新手 使用基于注释的Spring配置:

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

方面:

@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;
    }
}

如何拦截Spring框架本身调用的所有公共方法? (例如,在Spring创建TestComponent实例期间的TestComponent.init()) 目前,我只能通过调用:

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

3 个答案:

答案 0 :(得分:5)

这是Spring AOP遇到的常见问题。 Spring通过代理建议的类来完成AOP。在您的情况下,您的TestComponent实例将包装在运行时代理类中,该类为要应用的任何方面建议提供“挂钩”。当从外部类调用方法时,这非常有效,但是正如您所发现的那样,它不适用于内部调用。原因是内部调用不会通过代理障碍,因此不会触发方面。

主要有两种解决方法。一种是从上下文中获取(代理)bean的实例。这是你已经尝试过的成功。

另一种方法是使用称为加载时间编织的东西。使用它时,AOP建议通过将字节代码注入类定义,由自定义类加载器添加到类(“编织”到其中)。 Spring文档有more

还有第三种方法,称为“编译时编织”。在这种情况下,编译时,您的AOP建议会被静态编织到每个建议的类中。

答案 1 :(得分:0)

如果没有任何明确的方法,您无法拦截init(),有关详细信息,请参阅the SpringSource Jira

答案 2 :(得分:0)

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