Create Singleton with function/constructor arguments (usefull for e.g. injection)
We use spring to construct/inject our java beans. Here a snippet:
<bean id="myAppConfigs" class="my.cool.webapp.ApplicationConfig" scope="singleton">
<constructor-arg value="8080" />
<constructor-arg value="MyAppName1" />
</bean>
We use the singleton-pattern in
public static ApplicationConfig getCurrentInstance(ServletContext sctx) {
if (instance == null) {
WebApplicationContext wac = null;
if (sctx != null) {
wac = WebApplicationContextUtils.getWebApplicatio开发者_高级运维nContext(sctx);
}
return (ApplicationConfig) wac.getBean("myAppConfigs");
Since the bean is only reading some properties which are always the same I doubt there could be problems. But I'm still curious for a nice thread safe way to implement it There is of course the Double Checked Locking with usage of volatile which is threadsafe. But is there another way maybe to use the Initialization on demand holder idiom together with function/constructor arguments?
public static ApplicationConfig getCurrentInstance(ServletContext sctx) {
if (sctx == null) {
throw new AssertionError("ServletContext is null");
}
WebApplicationContext wac = WebApplicationContextUtils.getWebApplicationContext(sctx);
if (wac == null) {
throw new AssertionError("No ApplicationContext associated with ServletContext");
}
return (ApplicationConfig) wac.getBean("myAppConfigs");
}
This is plenty thread-safe. Better yet is to strive to use injection all the way (either through annotations or XML bean definitions), but that is not always possible.
Using Spring (DI) mixed with a singleton-pattern and explicit thread-synchronization is kind of anti-patternish and not really necesarry. The Spring bean factory is in itself thread-safe so you shouldn't need to add any additional locking/sync on top of it.
精彩评论