2

我是 Spring 框架的新手。当单例为真执行程序并在 xml 文件中指定销毁方法时,会执行指定的销毁方法,但单例为假时不执行。

在谷歌搜索时,我在某个地方知道 spring 无法管理非单例 bean 的完整生命周期。那么我们如何销毁该bean,以及spring无法管理非单例bean的完整生命周期的原因是什么。

提前致谢。

4

2 回答 2

2

如果 bean 是 Spring singleton,那么每次你请求它时,Spring 都会给你同样的一个。因此,Spring 必须始终保留此 bean 的句柄,因此 Spring 可以在ApplicationContext关闭时将其销毁。

如果 bean 不是 Spring singleton,那么每次你请求一个 bean 时,你都会得到它的一个新实例(具有相同的配置)。由于 Spring 不需要持有这些 bean,它们不会对它们保持句柄,并且没有对它们的句柄,它们如何在ApplicationContext关闭时调用方法来销毁它们?他们不能。

现在,您可能会问,为什么 Spring 不保留从非单例范围创建的 bean 的列表?嗯,一个问题是记忆。如果这是一个长期存在的应用程序,有很多请求创建了许多prototype作用域 bean,那么我们可以看到 Spring 跟踪很多对象,这可能会占用宝贵的内存。

当然还有其他潜在的问题,可能太多了,无法在此处列出,所以我将保留它。

于 2013-01-04T18:27:44.877 回答
1

参考文档,第 5.5.2 节:

与其他作用域相比,Spring 不管理原型 bean 的完整生命周期:容器实例化、配置和以其他方式组装原型对象,并将其交给客户端,而无需进一步记录该原型实例。因此,尽管在所有对象上调用初始化生命周期回调方法而不考虑范围,但在原型的情况下,不会调用配置的销毁生命周期回调。客户端代码必须清理原型范围的对象并释放原型 bean 持有的昂贵资源。要让 Spring 容器释放原型范围的 bean 持有的资源,请尝试使用自定义 bean 后处理器,它包含对需要清理的 bean 的引用。

在某些方面,Spring 容器对于原型作用域 bean 的作用是替代 Java 的 new 操作符。此后的所有生命周期管理都必须由客户处理。(有关 Spring 容器中 bean 生命周期的详细信息,请参阅第 5.6.1 节,“生命周期回调”。)

所以原因是他们决定在使用原型时不处理破坏。也许他们发现如果允许的话,可能会出现意想不到的问题。所以我很遗憾地说你必须自己处理破坏。

想多了,觉得有道理。如果您多次调用该方法,您将始终收到一个新的 bean 副本。如果要在容器关闭时调用每个副本的 dispose 方法,则 Spring Container 必须保留对每个副本的引用。这会造成令人不快的内存消耗。

于 2013-01-04T18:26:41.380 回答