Reputation: 1634
I am planning to use spring as a configuration service for our enterprise application.
This part has been well documented in spring reference guide and other blogs. Basically using a property file and a context:property-placeholder I plan to instantiate & populate values on a bean which is in turn used by the application.
There are occasions when the property file is changed and in that event I want the bean to reflect the changed values. I understand that ApplicationContext.refresh() is the way to refresh the bean and its configuration values. ApplicationContext.refresh() worked like a charm.
<context:property-override location="file:///d:/work/nano-coder/quickhacks/src/main/resources/myproperties.properties"/>
<bean id="myconfig" class="org.nanocoder.quickhacks.config.MyPropertyBean">
<property name="cacheSize" value="${registry.ehcache.size}"/>
<property name="httpHostName" value="${url.httpHostName}"/>
<property name="httpsHostName" value="${url.httpsHostName}"/>
<property name="imageServers">
<list>
<value>${url.imageserver1}</value>
<value>${url.imageserver2}</value>
<value>${url.imageserver3}</value>
</list>
</property>
</bean>
However when the context is being refreshed, I found that concurrent calls to ApplicationContext.getBean() or any getter operation on bean potentially fails due to IllegalStateException or BeanCreationException.
value = context.getBean("myconfig", MyPropertyBean.class).getHttpHostName();
Questions
Your pointers will be greatly appreciated.
Upvotes: 1
Views: 3061
Reputation: 12880
What you can do is create some wrapper around your config service and instead of refreshing existing context create a new one. When the new one is ready, start using this instead of the old one.
I'm not sure whether this is the best choice for config management but the code could look like this (later on one could at least introduce an interface with no spring dependency):
class MyConfig {
private ApplicationContext context;
public ApplicationContext getContext() {
return context;
}
public void refresh() {
context = new FileSystemXmlApplicationContext(..)
}
}
Upvotes: 1