Spring -我如何破坏我的原型作用域bean



我有一个单例bean,它有一个创建原型bean实例的方法。我使用这里记录的方法来获取原型bean的实例。

public class SingletonService implements ApplicationContextAware {
    private ApplicationContext applicationContext;
    public void go() {
        MyPrototypeBean prototype = applicationContext
            .getBean(MyPrototypeBean.class);
        prototype.doSomething();
    }
    @Override
    public void setApplicationContext(ApplicationContext applicationContext)
        throws BeansException {
        this.applicationContext = applicationContext;
    }
}

起初我认为这已经足够好了,当'go'方法返回时,我的'prototype'实例将超出作用域,这意味着该实例将没有引用并将被垃圾收集。

然而,一个同行从文档中指出了以下声明:

客户端代码必须清理原型作用域的对象并发布原型bean所持有的昂贵资源。

听起来好像Spring会保留一个引用,所以gc永远不会拾取它?如果是这种情况,我如何告诉Spring释放引用?文档提到我可以使用"自定义bean后处理器",但不清楚该处理器将适合何处以及它将运行什么代码。

提前感谢大家的帮助,罗伊

我想你误解了文档。这只是说Spring不会管理原型bean的生命周期,所以@PreDestroy(等等)方法需要由您自己的代码调用。Spring不会保留引用

为了让artbristol的答案更清晰:artbristol是正确的。Spring将创建代码所需的原型bean,但不会销毁它。这种行为是经过设计的,因为它被认为允许垃圾收集器在原型依赖超出作用域时"拾取"它会更有效。如果不这样做,那么Spring容器唯一的替代方法就是在创建原型bean的每个实例时保留对它们的引用。假设您的代码在每次调用MyPrototypeBean时都会创建一个新的MyPrototypeBean实例,这意味着您可能会生成太多的MyPrototypeBean实例,收集但不会被销毁,因为销毁只在关闭Spring容器时发生。您可以理解,这很容易导致快速内存泄漏。

因此,根据设计,原型bean由垃圾收集器处理,当它们超出作用域或当它们的销毁方法被手动调用时被销毁。

文档所说的是,如果MyPrototypeBean持有任何资源,例如数据库连接,那么这将阻止该资源被正确释放。因此,管理这一点成为编码器的责任。

最新更新