Сначала давайте посмотрим на служебный класс (большинство 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
}
}
Наконец, существует следующий управляемый bean-компонент Spring, который фактически вызывает метод '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
P.S. Я не стал вдаваться в , почему мне нужен этот служебный класс - пусть этого достаточно, чтобы у меня действительно была законная потребность обращаться к нему из статического контекста в любом месте приложения (после загрузки весеннего контекста, Конечно).