我是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();
答案 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()。