SGF-400 - Enable the ability to set the ClassLoader used by the Spring ApplicationContext created in the SpringContextBootstrappingInitializer for loading bean definition classes and resolving resources.

This commit is contained in:
John Blum
2015-04-18 00:19:29 -07:00
parent 3c9d9f7065
commit b9881dfad9
2 changed files with 164 additions and 13 deletions

View File

@@ -21,6 +21,7 @@ import java.util.Collection;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicReference;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -35,6 +36,7 @@ import org.springframework.context.event.ContextClosedEvent;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.context.event.SimpleApplicationEventMulticaster;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.data.gemfire.util.CollectionUtils;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
@@ -71,6 +73,8 @@ public class SpringContextBootstrappingInitializer implements Declarable, Applic
private static final ApplicationEventMulticaster applicationEventNotifier = new SimpleApplicationEventMulticaster();
private static final AtomicReference<ClassLoader> beanClassLoaderRef = new AtomicReference<ClassLoader>(null);
/* package-private */ static volatile ConfigurableApplicationContext applicationContext;
/* package-private */ static volatile ContextRefreshedEvent contextRefreshedEvent;
@@ -91,6 +95,24 @@ public class SpringContextBootstrappingInitializer implements Declarable, Applic
return applicationContext;
}
/**
* Sets the ClassLoader used by Spring ApplicationContext, created by this GemFire ("Bootstrapping") Initializer,
* when creating bean definition classes.
*
* @param beanClassLoader the ClassLoader used by the Spring ApplicationContext to load bean definition classes.
* @throws java.lang.IllegalStateException if the Spring ApplicationContext has already been created
* and initialized.
* @see java.lang.ClassLoader
*/
public static void setBeanClassLoader(ClassLoader beanClassLoader) {
if (applicationContext == null || !applicationContext.isActive()) {
beanClassLoaderRef.set(beanClassLoader);
}
else {
throw new IllegalStateException("The Spring ApplicationContext has already been initialized!");
}
}
/**
* Notifies any Spring ApplicationListeners of a current and existing ContextRefreshedEvent if the
* ApplicationContext had been previously created, initialized and refreshed before any ApplicationListeners
@@ -253,7 +275,7 @@ public class SpringContextBootstrappingInitializer implements Declarable, Applic
Assert.notNull(applicationContext, "The ConfigurableApplicationContext reference must not be null!");
applicationContext.addApplicationListener(this);
applicationContext.registerShutdownHook();
return applicationContext;
return setClassLoader(applicationContext);
}
/**
@@ -328,6 +350,24 @@ public class SpringContextBootstrappingInitializer implements Declarable, Applic
return applicationContext;
}
/**
* Sets the ClassLoader used to load bean definition classes on the Spring ApplicationContext.
*
* @param applicationContext the Spring ApplicationContext in which to configure the ClassLoader.
* @return the given Spring ApplicationContext.
* @see org.springframework.core.io.DefaultResourceLoader#setClassLoader(ClassLoader)
* @see java.lang.ClassLoader
*/
ConfigurableApplicationContext setClassLoader(ConfigurableApplicationContext applicationContext) {
ClassLoader beanClassLoader = beanClassLoaderRef.get();
if (applicationContext instanceof DefaultResourceLoader && beanClassLoader != null) {
((DefaultResourceLoader) applicationContext).setClassLoader(beanClassLoader);
}
return applicationContext;
}
/**
* Initializes a Spring ApplicationContext with the given parameters specified with a GemFire &lt;initializer&gt;
* block in cache.xml.