这样做安全吗(参见下面的代码)?
你必须定义safe.
The AbstractApplicationContext#refresh()
方法 javadoc 声明
由于这是一个启动方法,它应该销毁已经创建的
如果失败,则使用单例,以避免悬空资源。换句话说,
调用该方法后,要么全部单例,要么根本没有单例
应该被实例化。
基本上,上下文中的每个 bean 都将被销毁,并且对它们的所有引用都将被删除,使它们成为垃圾收集的候选者。您需要确保这些 Bean 有适当的方法来释放它们可能拥有的任何资源。有不同的方法可以做到这一点 http://docs.spring.io/spring/docs/4.0.0.RELEASE/spring-framework-reference/html/beans.html#beans-factory-lifecycle-default-init-destroy-methods
- 让你的班级实现
DisposableBean
界面。
- Add a
destroy-method
归因于你的<bean>
or @Bean
定义。
- 用注释方法
@PreDestroy
.
注意refresh()
通常会急切地刷新您的ApplicationContext
, IE。立即重新实例化所有 bean。发生这种情况时,您可能会注意到应用程序速度有所减慢。
我读到可以实现 bean 定义的更改
运行时的帮助StaticApplicationContext
or BeanPostProcessor
or
BeanFactoryPostProcessor
?那么区别是什么呢?
StaticApplicationContext
其中一个ApplicationContext
您自己注册 bean 定义的类。在您的示例中,bean 定义是从 XML 文件中解析并在幕后注册的。和StaticApplicationContext http://docs.spring.io/spring/docs/4.0.0.RELEASE/javadoc-api/org/springframework/context/support/StaticApplicationContext.html, 你用registerBeanDefinition(..) http://docs.spring.io/spring/docs/4.0.0.RELEASE/javadoc-api/org/springframework/context/support/GenericApplicationContext.html#registerBeanDefinition-java.lang.String-org.springframework.beans.factory.config.BeanDefinition-或其他registerXxx()
显式注册 bean 定义的方法。
A BeanFactoryPostProcessor
可以访问BeanFactory
正在使用,因此所有已注册的 bean 定义。因此,您可以检索任何BeanDefinition
你想要并修改它。作为javadocBeanFactoryPostProcess#postProcessBeanFactory(..) http://docs.spring.io/spring/docs/4.0.0.RELEASE/javadoc-api/org/springframework/beans/factory/config/BeanFactoryPostProcessor.html#postProcessBeanFactory-org.springframework.beans.factory.config.ConfigurableListableBeanFactory- states
所有 bean 定义都将被加载,但没有任何 bean 会被加载
尚未实例化。这允许覆盖或添加属性
甚至是急于初始化的bean。
您可以在之前更改 bean 定义ApplicationContext
实际上使用它。
最后,一个BeanPostProcessor
不改变 bean 定义。您可以使用BeanPostProcessor
改变 bean 的创建方式,但底层BeanDefinition
将保持不变。
对于您的编辑(比实际答案更大:))
据我了解 BeanPostProcess 允许您修改已经存在的
通过使用代理包装对象,在运行时生成 bean 实例。我是吗
正确的?
它不仅仅是用于代理,您可以对对象执行任何您想要的操作:修改其属性,在其他上下文中注册它,使其null
等等。这围绕着 bean 定义进行。
AbstractApplicationContext#refresh()
删除所有单例 bean 并
重新创建它们。
但是如果我想更改原型/自定义范围的定义
豆角,扁豆?如果我有两个 bean:A 和 B。A 引用了 B。如果我
更改 bean 定义,使其不包含
定义B.那么B的实例就会被销毁,但是新的实例
不会被创建。比 A 将获得空依赖项。我对吗?
In an ApplicationContext
,您声明您的 bean 定义。如果您要更改 bean 定义,请在BeanFactoryPostProcessor
或者在上下文配置中以不同方式声明它。
对于依赖项,如果您销毁B
bean 定义,不会有要注入的 beanA
Spring 会抱怨,抛出NoSuchBeanDefinitionException
。 Bean注入永远不会注入null
除非你明确告诉它。
StaticApplicationContext
and BeanFactoryPostProcessor
两者都允许我
在运行时更改 bean 定义。但有什么区别,
优点缺点?
两者的目的完全不同。StaticApplicationContext
is an ApplicationContext
执行。在这里,您声明 bean 定义。 ABeanFactoryPostProcessor
用于根据您想要实现的任何条件以任何方式修改这些 bean 定义。
为什么Spring有3种机制来实现相同的目标。你能做一个
之间的简短比较(或用例示例)AbstractApplicationContext#refresh()
, StaticApplicationContext
and
BeanFactoryPostProcessor
please.
目标不一样。一个ApplicationContext
不同于BeanFactoryPostProcessor
并在上下文生命周期的不同时间发挥作用(请参阅上一个问题中的漂亮图表)。
我没有适合您的用例。了解上述各项的作用,当您遇到特定要求时,您就会知道何时应用它们。