我是Spring框架的新手。当使用singleton执行程序为true并在xml文件中指定destroy方法时,将执行指定的destroy方法,但是当singleton为false时,它不会执行。
在谷歌搜索时,我发现春天无法管理非单身豆的完整生命周期。那么我们怎样才能破坏那个bean,以及spring无法管理非单一bean的完整生命周期的原因是什么。
提前致谢。
答案 0 :(得分:2)
如果一个bean是一个Spring singleton
,那么每次你要求它时,Spring都会给你一个相同的bean。因此,Spring必须始终保持对这个bean的处理,因此Spring可以在ApplicationContext
关闭时销毁它。
如果bean不是Spring singleton
,那么每次请求bean时,都会得到一个新的实例(具有相同的配置)。由于Spring不需要保留这些bean,因此它们不会对它们进行处理,如果没有句柄,它们如何在ApplicationContext
关闭时调用方法来销毁它们?他们不能。
现在,您可能会问,为什么Spring不会保留从非单例范围创建的bean列表?那么,一个问题就是记忆。如果这是一个长期存在的应用程序,有很多请求创建了许多prototype
范围的bean,那么我们可以看到Spring跟踪很多对象,这可能会占用宝贵的内存。
肯定存在其他潜在的问题,可能会在这里列出太多,所以我会留下它。
答案 1 :(得分:1)
从reference documentation,第5.5.2节:
与其他作用域相比,Spring不管理原型bean的完整生命周期:容器实例化,配置和组装原型对象,并将其交给客户端,没有该原型实例的进一步记录。因此,尽管无论范围如何都在所有对象上调用初始化生命周期回调方法,但在原型的情况下,不会调用已配置的销毁生命周期回调。客户端代码必须清理原型范围的对象并释放原型bean所持有的昂贵资源。要让Spring容器释放原型范围的bean所拥有的资源,请尝试使用自定义bean后处理器,它包含对需要清理的bean的引用。
在某些方面,Spring容器关于原型范围bean的角色是Java new运算符的替代品。超过该点的所有生命周期管理必须由客户端处理。 (有关Spring容器中bean的生命周期的详细信息,请参见第5.6.1节“生命周期回调”。)
原因是他们在使用原型时决定不处理破坏。也许他们发现如果被允许可能会出现意外问题。所以我很遗憾地说你必须自己处理破坏。
多想一想,我觉得这很有道理。如果多次调用该方法,您将始终收到该bean的新副本。如果在容器关闭时调用每个副本的dispose方法,Spring容器必须保持对每个副本的引用。这会造成令人不愉快的内存消耗。