Spring原型Bean能否与try-with-resources机制结合使用?
问题场景与解答
场景代码
Spring配置类(创建原型Bean)
@Configuration public class ResourceCreation { @Bean() @Scope("prototype") public MyResource createResource() { return new MyResource("Test"); } }
Bean获取工厂类
public class ResourceFactory { @Autowired ApplicationContext m_applicationContext; public static MyResource generateResource() { return m_applicationContext.getBean(MyResource.class); } }
资源使用代码
try (MyResource resource = ResourceFactory.generateResource()) { ... }
问题
- 这种用法是否存在问题?
- 由于Spring容器应管理原型Bean的生命周期,try块结束后MyResource的
close()方法是否会被调用?
解答
首先修复代码中的致命错误
ResourceFactory的generateResource()是静态方法,却直接引用了@Autowired注入的实例变量m_applicationContext——该变量属于类的实例对象,静态方法执行时实例还未初始化,运行时必然抛出NullPointerException。修复方案二选一:
- 将
generateResource()改为非静态方法,调用时使用ResourceFactory的Spring托管实例获取Bean; - 让
ResourceFactory实现ApplicationContextAware接口,通过静态方式持有ApplicationContext引用。
核心问题解答
用法存在问题:
- 除了上述空指针问题,Spring对原型Bean的生命周期规则是:容器仅负责创建Bean,一旦Bean被交付给调用者,容器就不再跟踪、管理它的后续销毁或资源释放操作。但这里的try-with-resources是Java语法层面的资源管理机制,和Spring的生命周期管理是相互独立的两套逻辑。
try块结束后
close()方法会被调用:- 因为
MyResource实现了AutoCloseable接口,而try-with-resources是Java原生的自动资源管理语法,无论代码正常执行完成还是抛出异常,只要try块执行完毕,JVM都会自动调用该资源的close()方法。这个过程和Spring容器无关,完全由Java语言本身触发。
- 因为
总结:Spring不会主动管理原型Bean的关闭,但try-with-resources会触发close(),前提是先修复ResourceFactory中的空指针问题。
内容的提问来源于stack exchange,提问作者lightrek
相关产品推荐
相关产品推荐

