我已经读过动态bean定义的变化.我在一个简单的代码示例中尝试它(参见下面的代码),我发现它在我不想停止服务器但添加/更改bean定义的情况下非常有吸引力.
问题:
我已经读过,有可能在运行时通过StaticApplicationContex或BeanPostProcessor或帮助实现bean定义更改BeanFactoryPostProcessor?那么区别是什么呢?
public class Main {
final static String header = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
"<beans xmlns=\"http://www.springframework.org/schema/beans\"\n" +
" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n" +
" xmlns:context=\"http://www.springframework.org/schema/context\"\n" +
" xsi:schemaLocation=\"http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd\">\n" +
" <context:annotation-config />\n" +
" <context:component-scan base-package=\"vbah\"/>";
final static String contextA =
"<bean id=\"test\" class=\"java.lang.String\">\n" +
"\t\t<constructor-arg value=\"fromContextA\"/>\n" +
"</bean></beans>";
final static String contextB =
"<bean id=\"test\" class=\"java.lang.String\">\n" +
"\t\t<constructor-arg value=\"fromContextB\"/>\n" +
"</bean></beans>";
public static void main(String[] args) throws IOException {
//create a single context file
final File contextFile = new File("src/resources/spring-config.xml");
//write the first context into it
FileUtils.writeStringToFile(contextFile, header + contextA);
//create a spring context
FileSystemXmlApplicationContext context = new FileSystemXmlApplicationContext(
new String[]{contextFile.getPath()}
);
//echo "fromContextA"
System.out.println(context.getBean("test"));
//write the second context into it
FileUtils.writeStringToFile(contextFile, header + contextB);
//refresh the context
context.refresh();
//echo "fromContextB"
System.out.println(context.getBean("test"));
}
}
Run Code Online (Sandbox Code Playgroud)编辑:
你能否回答以下问题:
BeanPostProcess允许您通过使用代理包装对象来在运行时修改已存在的bean实例.我对吗?AbstractApplicationContext#refresh()删除所有单例bean并重新创建它们.
null依赖.我对吗?StaticApplicationContext并且BeanFactoryPostProcessor都允许我在运行时更改bean定义.但有什么区别,利弊?
AbstractApplicationContext#refresh(),StaticApplicationContext并BeanFactoryPostProcessor请.Sot*_*lis 12
这样做是否安全(见下面的代码)?
你必须定义安全.
该AbstractApplicationContext#refresh()方法的javadoc状态
由于这是一个启动方法,它应该销毁已创建的单例,如果它失败,以避免悬空资源.换句话说,在调用该方法之后,应该实例化所有单个或不单个.
基本上,上下文中的每个bean都将被销毁,并且对它们的所有引用都将被删除,这使它们成为垃圾收集的候选者.您需要确保这些bean有适当的方法来释放他们可能拥有的任何资源.有不同的方法可以做到这一点
DisposableBean接口.destroy-method向您的<bean>或@Bean定义添加属性.@PreDestroy.请注意,refresh()通常会急切地刷新你的ApplicationContext,即.立即重新实例化所有bean.当发生这种情况时,您可能会发现应用程序有些速度变慢.
我已经读过,有可能在运行时通过
StaticApplicationContext或BeanPostProcessor或 帮助实现bean定义更改BeanFactoryPostProcessor?那么区别是什么呢?
StaticApplicationContext是ApplicationContext您自己注册bean定义的类之一.在您的示例中,bean定义从XML文件中解析并在后台注册.使用StaticApplicationContext,您可以使用registerBeanDefinition(..)或其他registerXxx()方法显式注册bean定义.
A BeanFactoryPostProcessor可以访问BeanFactory正在使用的内容,因此可以访问已注册的所有bean定义.因此,您可以检索任何BeanDefinition您想要的并修改它.作为BeanFactoryPostProcess#postProcessBeanFactory(..)状态的javadoc
将加载所有bean定义,但尚未实例化任何bean.这允许覆盖或添加属性,甚至是初始化bean.
您可以在ApplicationContext实际使用之前更改bean定义.
最后,a BeanPostProcessor不会改变bean的定义.您可以使用a BeanPostProcessor来更改bean的创建方式,但底层BeanDefinition将保持不变.
对于你的编辑(比实际答案大:))
据我所知,BeanPostProcess允许您通过使用代理包装对象来在运行时修改已存在的bean实例.我对吗?
它不仅仅用于代理,你可以用对象做任何你想要的事情:修改它的属性,在其他一些上下文中注册它,制作它null等等.这就是bean的定义.
AbstractApplicationContext#refresh()删除所有单例bean并重新创建它们.但是如果我想改变prototype/custom scoped bean的定义呢?如果我有两个bean:A和B. A引用了B.如果我以不包含B的定义的方式更改bean定义.B实例将被销毁,但新实例不会被创造.比A将获得null依赖.我对吗?
在一个ApplicationContext,你声明你的bean定义.如果您要更改bean定义,请BeanFactoryPostProcessor在上下文配置中更改或以不同方式声明它.
对于依赖项,如果你破坏Bbean定义,就不会有一个bean注入,A而Spring会抱怨,抛出NoSuchBeanDefinitionException.Bean注入永远不会注入,null除非您明确告诉它.
StaticApplicationContext并且BeanFactoryPostProcessor都允许我在运行时更改bean定义.但有什么区别,利弊?
两者完全不同.StaticApplicationContext是一个ApplicationContext实现.在这里,您声明了bean定义.A BeanFactoryPostProcessor用于根据您要实现的任何条件以任何方式修改这些bean定义.
为什么Spring有3种机制来实现同样的目标.你能简单比较(或usecases的例子)
AbstractApplicationContext#refresh(),StaticApplicationContext并BeanFactoryPostProcessor请.
目标不一样.An ApplicationContext不同于a BeanFactoryPostProcessor并且在上下文生命周期中的不同时间发挥作用(请参阅前一个问题中的漂亮图表).
我没有你的用例.了解上述每项内容可以做什么,并且当您获得特定要求时,您将知道何时应用它们.
| 归档时间: |
|
| 查看次数: |
9594 次 |
| 最近记录: |