目录
Spring动态代理(AOP)问题汇总
在同一个类中,一个方法调用另外一个动态代理方法(比如有@Async、@Transactional),动态代理是不会生效的,而@Configuration注解配置的类却可以代理(@Bean注解的方法)?
示例代码如下:
@Component
public class Example {
@Async
public String sayHello(String name) {
return "hi~ " + name;
}
@Async
public String sayGoodBye(String name) {
return sayHello(name) + " good bye";
}
}
@Configuration
public class BeanConfig {
@Bean
public T1 t1() {
return new T1();
}
@Bean
public String test1() {
return "test1" + t1();
}
@Bean
public String test2() {
return "test2" + t1();
}
public String test3() {
return "test3" + t1();
}
static class T1 {
}
}
我们知道cglib动态代理是通过继承父类,然后重写父类方法来实现代理的。根据java的多态性,重写了父类的方法,方法执行时肯定会执行子类的实现,也就是说动态代理会生效的。但是,结合上面的例子,我们发现@Async注解的方法没有生效,但是@Bean注解的方法却生效了。
原因: 我们可以先调试一下,@Bean注解的方法this对象是cglib增强的类的实例,
而@Async注解的方法,在执行到方法内部时,this对象不是cglib增强类的实例,所以动态代理不会生效。
我们在结合源代码分析,CglibMethodInvocation调用链执行到最后执行invokeJoinpoint()方法时,传入的对象确实是原来未增强的对象
另外@Configuration注解的类是通过ConfigurationClassEnhancer#enhance方法创建增强类的;而普通的AOP代理是通过ProxyFactory#getProxy方法创建增强类的,它支持cglib和jdk代理这两种方式。
本文探讨了Spring框架中AOP(面向切面编程)的动态代理机制,特别是当在一个类内调用带有@Async或@Transactional等注解的方法时,动态代理为何不生效的问题。并对比了@Configuration注解配置类中@Bean注解的方法为何能生效。
问题汇总&spm=1001.2101.3001.5002&articleId=118862964&d=1&t=3&u=d88fadfecff94920a4d2a604fbf707c8)
1万+

被折叠的 条评论
为什么被折叠?



