【发布时间】:2009-11-11 19:51:49
【问题描述】:
首先让我们看一下实用程序类(大多数javadoc已被删除以简化示例):
public class ApplicationContextUtils {
/**
* The application context; care should be taken to ensure that 1) this
* variable is assigned exactly once (in the
* {@link #setContext(ApplicationContext)} method, 2) the context is never
* reassigned to {@code null}, 3) access to the field is thread-safe (no race
* conditions can occur)
*/
private static ApplicationContext context = null;
public static ApplicationContext getContext() {
if (!isInitialized()) {
throw new IllegalStateException(
"Context not initialized yet! (Has the "
+ "ApplicationContextProviderBean definition been configured "
+ "properly and has the web application finished "
+ "loading before you invoked this method?)");
}
return context;
}
public static boolean isInitialized() {
return context == null;
}
@SuppressWarnings("unchecked")
public static <T> T getBean(final String name, final Class<T> requiredType) {
if (requiredType == null) {
throw new IllegalArgumentException("requiredType is null");
}
return (T) getContext().getBean(name, requiredType);
}
static synchronized void setContext(final ApplicationContext theContext) {
if (theContext == null) {
throw new IllegalArgumentException("theContext is null");
}
if (context != null) {
throw new IllegalStateException(
"ApplicationContext already initialized: it cannot be done twice!");
}
context = theContext;
}
private ApplicationContextUtils() {
throw new AssertionError(); // NON-INSTANTIABLE UTILITY CLASS
}
}
最后,有以下帮助 Spring 托管 bean 实际调用了 'setContext' 方法:
public final class ApplicationContextProviderBean implements
ApplicationContextAware {
public void setApplicationContext(
final ApplicationContext applicationContext) throws BeansException {
ApplicationContextUtils.setContext(applicationContext);
}
}
Spring 会在应用启动后调用一次 setApplicationContext 方法。假设 nincompoop 之前没有调用 ApplicationContextUtils.setContext(),它应该锁定对实用程序类中上下文的引用,允许对 getContext() 的调用成功(意味着 isInitialized() 返回 true)。
我只是想知道这个类是否违反了良好编码实践的任何原则,特别是在线程安全方面(但欢迎发现其他愚蠢行为)。
感谢 StackOverflow 帮助我成为更好的程序员!
问候, LES
附:我没有进入为什么我需要这个实用程序类 - 让我确实有合法需要从应用程序中任何位置的静态上下文访问它就足够了(在加载弹簧上下文之后,当然)。
【问题讨论】:
-
"大多数 javadoc 已被删除以简化示例" -> 大声笑
标签: java multithreading spring static thread-safety