Spring Bean自注入是否会引发内存泄漏?
Bean自注入是否会引发内存泄漏?
问题背景与疑问
在Spring中,Bean由代理对象封装,外部调用Bean方法时会触发代理对象的方法,Spring正是通过这一机制实现事务管理。但如果在同一个Bean内部调用方法,且希望被调用方法与调用方处于不同事务中,直接调用无法实现——因为内部方法调用不会经过事务代理对象。为解决这个问题,有人提出了Bean自注入方案,示例代码如下:
@Service public class MyService{ @Autowired public MyService myService; @Transactional(propagation = Propagation.REQUIRES_NEW) public void method1(){ method2();// 与method1处于同一事务 myService.method2();// 与method1处于独立事务 } @Transactional(propagation = Propagation.REQUIRES_NEW) public void method2(){ } }
疑问:这种Bean自注入方式是否会引发内存泄漏?外部的MyService Bean包含注入的myService,而myService又包含MyService类型的属性,如此循环嵌套……
回答
这种自注入方式不会引发内存泄漏,核心原因如下:
- Spring容器中默认的Bean是单例模式,你注入的
myService其实就是当前Bean自己的引用,并非创建了一个新的MyService实例。整个结构里只有一个MyService对象,只是它自己持有了指向自身的引用,不存在“循环嵌套的多个实例”这种情况。 - Java的垃圾回收机制可以处理这种自引用的对象:当容器销毁Bean时,只要没有其他外部引用指向这个Bean,即使它自己持有自身的引用,GC也能正常回收该对象,不会造成内存泄漏。
另外需要注意,这种自注入方式在代理类型上有一些细节:如果Bean是通过JDK动态代理生成的(实现了接口),自注入的会是代理对象;如果是CGLIB代理(基于类继承),注入的也是代理实例,但无论哪种情况,本质都是同一个单例对象的引用,不会产生内存问题。
内容的提问来源于stack exchange,提问作者Ahmet Erdem
相关产品推荐
相关产品推荐

