First let's look at the utility class (most javadoc has been removed to simply the example):
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
}
}
Finally, there is the following helper Spring managed bean that actually calls the 'setContext' method:
public final class ApplicationContextProviderBean implements
ApplicationContextAware {
public void setApplicationContext(
final ApplicationContext applicationContext) throws BeansException {
ApplicationContextUtils.setContext(applicationContext);
}
}
Spring will call the setApplicationContext method once after the app is started. Assuming a nincompoop has not previously called ApplicationContextUtils.setContext(), that should lock in the reference to the context in the utility class, allowing calls to getContext() to success (meaning that isInitialized() returns true).
I just want to know if this class violates any principles of good coding practices, with respect to thread safety in particular (but other stupidities found are welcome).
Thanks for helping me to become a better programmer, StackOverflow!
Regards, LES
P.S. I didn't go into why I need this utility class - let it suffice that I indeed do have a legitimate need to access it from a static context anywhere in the application (after the spring context has loaded, of course).