我们使用 spring 来构造/注入(inject)我们的 java beans。这是一个片段:
<bean id="myAppConfigs" class="my.cool.webapp.ApplicationConfig" scope="singleton">
<constructor-arg value="8080" />
<constructor-arg value="MyAppName1" />
</bean>
我们在
中使用单例模式public static ApplicationConfig getCurrentInstance(ServletContext sctx) {
if (instance == null) {
WebApplicationContext wac = null;
if (sctx != null) {
wac = WebApplicationContextUtils.getWebApplicationContext(sctx);
}
return (ApplicationConfig) wac.getBean("myAppConfigs");
由于 bean 仅读取一些始终相同的属性,因此我怀疑可能存在问题。但我仍然对一种很好的线程安全方式来实现它感到好奇 当然有Double Checked Locking with usage of volatile这是线程安全的。 但是还有其他方法可以使用 Initialization on demand holder idiom 与函数/构造函数参数一起?
最佳答案
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");
}
这是足够线程安全的。更好的是努力一直使用注入(inject)(通过注释或 XML bean 定义),但这并不总是可能的。
将 Spring (DI) 与单例模式和显式线程同步混合使用是一种反模式,并不是真正必要的。 Spring bean 工厂本身是线程安全的,因此您不需要在其上添加任何额外的锁定/同步。
关于java - 使用函数/构造函数参数创建单例(对于例如注入(inject)很有用),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6746570/