概述
在前面一篇文章中,介绍,在一个bean中注入自己,如果有@async和@transaction,如果使用@autowire注入自身,会报循环依赖,如果使用beanfactoryaware注入自己,会使得@transaction失效。 例如:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
@service
public class myservice implements beanfactoryaware{
private myservice self;
//事务注解无效
@transactional
public void notwork() {
...
}
@async
public future async(){
...
}
@override
public void setbeanfactory(beanfactory beanfactory) throws beansexception {
self= beanfactory.getbean(myservice. class );
}
}
|
当时只是简单提了一下,这篇文章就是来介绍为什么会失效。
一般情况
造成上面的情况需要满足以下条件:
造成的结果:除@async外的注解生效,其他的都不生效,如下图
而正常代理的应该是下图:
原因
首先想到的是@async注解的处理方式可能和其他的不一样。在asyncannotationbeanpostprocessor的实现中(具体代码是在其父类abstractadvisingbeanpostprocessor),发现一个问题,
正常情况下,进来的bean已经是被代理的动态代理类,而失效的时候,进来的确实实际的类,如下图:
然后在分析下代码,如果是实际的类,走到69行的时候,返回是true,把@aysnc的advisor加入到动态道理中,而如果是实际的类,走到83行的时候,就会创建代理类,只把@aysnc的advisor加入到动态代理中,所已诸如@transaction就会失效。
为什么进来的不是代理类
其实唯一的区别就是beanfactoryaware中,是否通过了beanfactory获取了自己。那为什么使用beanfactory获取了自己,后续的beanpostprocessor中就不是代理了?如果熟悉spring @transaction加载机制的就知道,诸如@transaction,@retryable 注解的动态代理创建是在annotationawareaspectjautoproxycreator中创建的。通过debug发现,经过annotationawareaspectjautoproxycreator后,我们的动态代理竟然没有加上。
再看一下annotationawareaspectjautoproxycreator中的实现,但是经过他却没有生成代理类。原因竟然是提前暴露的map里面竟然有“myservice”,
他是什么时候暴露出来的呢?其实就是在
1
2
3
4
|
@override
public void setbeanfactory(beanfactory beanfactory) throws beansexception {
self= beanfactory.getbean(myservice. class );
}
|
那么,一切水落石出了,在实例myservice中,触发了beanfactoryaware,通过beanfactory.getbean(myservice.class);中创建了代理类(tips:当前代理类并没有包含@async的adivisor),因为现在spring其实正是在创建myservice这个bean,还没有放入到beanfactory中。然后我们再这个过程中又触发了一次beanfactory.getbean(myservice.class);导致创建代理并返回后,加入到了到了提前暴露的map中。导致后面的一系列问题。感觉有点绕。看图说话:
正常情况,应该是如下流程:
异常情况却是这样的
小结
正常情况下,还是使用@autowire来注入把(如果使用autowire,上述情况直接回抛出循环依赖)。当然,出现了问题,也是不能放过了,要知其然还要知其所以然!
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持快网idc。
原文链接:http://www.cnblogs.com/lizo/p/8652576.html
相关文章
- 64M VPS建站:如何选择最适合的网站建设平台? 2025-06-10
- ASP.NET本地开发时常见的配置错误及解决方法? 2025-06-10
- ASP.NET自助建站系统的数据库备份与恢复操作指南 2025-06-10
- 个人网站服务器域名解析设置指南:从购买到绑定全流程 2025-06-10
- 个人网站搭建:如何挑选具有弹性扩展能力的服务器? 2025-06-10
- 2025-07-10 怎样使用阿里云的安全工具进行服务器漏洞扫描和修复?
- 2025-07-10 怎样使用命令行工具优化Linux云服务器的Ping性能?
- 2025-07-10 怎样使用Xshell连接华为云服务器,实现高效远程管理?
- 2025-07-10 怎样利用云服务器D盘搭建稳定、高效的网站托管环境?
- 2025-07-10 怎样使用阿里云的安全组功能来增强服务器防火墙的安全性?
快网idc优惠网
QQ交流群
-
2025-05-25 49
-
2025-05-25 31
-
详解Spring Cloud Stream使用延迟消息实现定时任务(RabbitMQ)
2025-05-29 43 -
使用自助建站微信小程序时,怎样选择合适的模板以匹配品牌形象?
2025-06-04 78 -
2025-05-29 88