SGF-425 - Allow early initialization and re-initialization of LazyWiringDeclarableSupport instances.
This commit is contained in:
@@ -25,69 +25,82 @@ import com.gemstone.gemfire.cache.CacheCallback;
|
||||
import com.gemstone.gemfire.cache.Declarable;
|
||||
|
||||
/**
|
||||
* Convenience class for Spring-aware GemFire Declarable components. Provides a
|
||||
* reference to the current Spring application context, e.g. for bean lookup or
|
||||
* resource loading.
|
||||
* Convenience class for Spring-aware GemFire Declarable components. Provides a reference to the current
|
||||
* Spring ApplicationContext, e.g. for Spring bean lookup or resource loading.
|
||||
*
|
||||
* Note that in most cases, one can just declare the same components as Spring
|
||||
* beans, through {@link RegionFactoryBean} which gives access to the full
|
||||
* container capabilities and does not enforce the {@link Declarable} interface
|
||||
* Note that in most cases, one can just declare the same components as Spring beans, through {@link RegionFactoryBean}
|
||||
* which gives access to the full Spring container capabilities and does not enforce the {@link Declarable} interface
|
||||
* to be implemented.
|
||||
*
|
||||
* @author Costin Leau
|
||||
* @author John Blum
|
||||
* @see org.springframework.beans.factory.BeanFactory
|
||||
* @see org.springframework.beans.factory.access.BeanFactoryReference
|
||||
* @see com.gemstone.gemfire.cache.CacheCallback
|
||||
* @see com.gemstone.gemfire.cache.Declarable
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public abstract class DeclarableSupport implements CacheCallback, Declarable {
|
||||
|
||||
private String factoryKey = null;
|
||||
private String beanFactoryKey = null;
|
||||
|
||||
private BeanFactoryReference bfReference = null;
|
||||
private BeanFactoryReference beanFactoryReference = null;
|
||||
|
||||
public DeclarableSupport() {
|
||||
}
|
||||
|
||||
/**
|
||||
* This implementation uses this method as a lifecycle hook to initialize
|
||||
* the bean factory locator.
|
||||
*
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @see #setFactoryKey(String)
|
||||
* Gets a reference to the configured Spring BeanFactory.
|
||||
*
|
||||
* @return a Spring BeanFactory reference.
|
||||
* @see org.springframework.beans.factory.BeanFactory
|
||||
*/
|
||||
@Override
|
||||
public final void init(Properties props) {
|
||||
bfReference = new GemfireBeanFactoryLocator().useBeanFactory(factoryKey);
|
||||
initInstance(props);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the current instance based on the given properties.
|
||||
*
|
||||
* @param props the Properties used to initialize this Declarable.
|
||||
* @see com.gemstone.gemfire.cache.Declarable#init(java.util.Properties)
|
||||
* @see java.util.Properties
|
||||
*/
|
||||
protected void initInstance(Properties props) {
|
||||
}
|
||||
|
||||
protected BeanFactory getBeanFactory() {
|
||||
return bfReference.getFactory();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
bfReference.release();
|
||||
bfReference = null;
|
||||
return beanFactoryReference.getFactory();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the key under which the enclosing BeanFactory can be found. Needed only if multiple BeanFactories
|
||||
* are used with GemFire inside the same class loader / class space.
|
||||
*
|
||||
* @see GemfireBeanFactoryLocator
|
||||
* @param key a String specifying the key used to lookup the "enclosing" BeanFactory in the presenence of
|
||||
* multiple BeanFactories.
|
||||
*
|
||||
* @param key a String specifying the key used to lookup the "enclosing" BeanFactory in the presence
|
||||
* of multiple BeanFactories.
|
||||
* @see org.springframework.data.gemfire.GemfireBeanFactoryLocator
|
||||
*/
|
||||
public void setFactoryKey(String key) {
|
||||
this.factoryKey = key;
|
||||
this.beanFactoryKey = key;
|
||||
}
|
||||
|
||||
/**
|
||||
* This Declarable implementation uses the init method as a lifecycle hook to initialize the bean factory locator.
|
||||
*
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @see org.springframework.data.gemfire.GemfireBeanFactoryLocator
|
||||
* @see #setFactoryKey(String)
|
||||
*/
|
||||
@Override
|
||||
public final void init(Properties parameters) {
|
||||
beanFactoryReference = new GemfireBeanFactoryLocator().useBeanFactory(beanFactoryKey);
|
||||
initInstance(parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize this Declarable object with the given Properties.
|
||||
*
|
||||
* @param props the Properties (parameters) used to initialize this Declarable.
|
||||
* @see com.gemstone.gemfire.cache.Declarable#init(java.util.Properties)
|
||||
* @see java.util.Properties
|
||||
* @see #init(Properties)
|
||||
*/
|
||||
protected void initInstance(Properties props) {
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
@Override
|
||||
public void close() {
|
||||
beanFactoryReference.release();
|
||||
beanFactoryReference = null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -47,6 +47,7 @@ import org.springframework.util.StringUtils;
|
||||
* by {@link com.gemstone.gemfire.cache.CacheFactory}.
|
||||
*
|
||||
* @author Costin Leau
|
||||
* @author John Blum
|
||||
*/
|
||||
public class GemfireBeanFactoryLocator implements BeanFactoryLocator, BeanFactoryAware, BeanNameAware, DisposableBean,
|
||||
InitializingBean {
|
||||
@@ -62,19 +63,19 @@ public class GemfireBeanFactoryLocator implements BeanFactoryLocator, BeanFactor
|
||||
|
||||
private static class SimpleBeanFactoryReference implements BeanFactoryReference {
|
||||
|
||||
private BeanFactory bf;
|
||||
private BeanFactory beanFactory;
|
||||
|
||||
SimpleBeanFactoryReference(BeanFactory bf) {
|
||||
this.bf = bf;
|
||||
SimpleBeanFactoryReference(BeanFactory beanFactory) {
|
||||
this.beanFactory = beanFactory;
|
||||
}
|
||||
|
||||
public BeanFactory getFactory() {
|
||||
Assert.notNull(bf, "beanFactory already released or closed");
|
||||
return bf;
|
||||
Assert.state(beanFactory != null, "The BeanFactory has already been released or closed");
|
||||
return beanFactory;
|
||||
}
|
||||
|
||||
public void release() throws FatalBeanException {
|
||||
bf = null;
|
||||
beanFactory = null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -106,7 +107,7 @@ public class GemfireBeanFactoryLocator implements BeanFactoryLocator, BeanFactor
|
||||
// add aliases
|
||||
if (StringUtils.hasText(factoryName)) {
|
||||
String[] aliases = beanFactory.getAliases(factoryName);
|
||||
names = (String[]) ObjectUtils.addObjectToArray(aliases, factoryName);
|
||||
names = ObjectUtils.addObjectToArray(aliases, factoryName);
|
||||
|
||||
for (String name : names) {
|
||||
if (log.isDebugEnabled())
|
||||
@@ -161,4 +162,5 @@ public class GemfireBeanFactoryLocator implements BeanFactoryLocator, BeanFactor
|
||||
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
|
||||
this.beanFactory = beanFactory;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -19,17 +19,15 @@ package org.springframework.data.gemfire;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.beans.factory.wiring.BeanConfigurerSupport;
|
||||
import org.springframework.beans.factory.wiring.BeanWiringInfo;
|
||||
import org.springframework.beans.factory.wiring.BeanWiringInfoResolver;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.event.ContextRefreshedEvent;
|
||||
import org.springframework.data.gemfire.support.SpringContextBootstrappingInitializer;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import com.gemstone.gemfire.cache.Declarable;
|
||||
@@ -41,10 +39,13 @@ import com.gemstone.gemfire.cache.Declarable;
|
||||
* @author John Blum
|
||||
* @see java.util.Properties
|
||||
* @see org.springframework.beans.factory.DisposableBean
|
||||
* @see org.springframework.beans.factory.wiring.BeanConfigurerSupport
|
||||
* @see org.springframework.beans.factory.wiring.BeanWiringInfo
|
||||
* @see org.springframework.context.ApplicationListener
|
||||
* @see org.springframework.context.event.ContextRefreshedEvent
|
||||
* @see org.springframework.data.gemfire.DeclarableSupport
|
||||
* @see org.springframework.data.gemfire.WiringDeclarableSupport
|
||||
* @see org.springframework.data.gemfire.support.SpringContextBootstrappingInitializer
|
||||
* @see com.gemstone.gemfire.cache.Declarable
|
||||
* @since 1.3.4
|
||||
*/
|
||||
@@ -52,15 +53,18 @@ import com.gemstone.gemfire.cache.Declarable;
|
||||
public abstract class LazyWiringDeclarableSupport implements ApplicationListener<ContextRefreshedEvent>,
|
||||
Declarable, DisposableBean {
|
||||
|
||||
// The name of the template bean defined in the Spring context for wiring this Declarable instance.
|
||||
// name of the template bean defined in the Spring context for wiring this Declarable instance.
|
||||
protected static final String BEAN_NAME_PARAMETER = "bean-name";
|
||||
|
||||
// atomic reference to the parameter passed by GemFire when this Declared was constructed
|
||||
// atomic reference to the parameter passed by GemFire when this Declarable was constructed
|
||||
// and the init method was called.
|
||||
private final AtomicReference<Properties> parametersReference = new AtomicReference<Properties>();
|
||||
|
||||
// condition determining the initialization state of this Declarable
|
||||
volatile boolean initialized = false;
|
||||
|
||||
private String factoryKey = null;
|
||||
|
||||
/**
|
||||
* Constructs an instance of the LazyWiringDeclarableSupport class registered with the
|
||||
* SpringContextBootstrappingInitializer. This Declarable will receive notifications from the
|
||||
@@ -75,6 +79,30 @@ public abstract class LazyWiringDeclarableSupport implements ApplicationListener
|
||||
SpringContextBootstrappingInitializer.register(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the key used to locate (lookup) the Spring BeanFactory.
|
||||
*
|
||||
* @param factoryKey the key used to locate the Spring BeanFactory.
|
||||
* @see org.springframework.beans.factory.BeanFactory
|
||||
* @see org.springframework.data.gemfire.GemfireBeanFactoryLocator
|
||||
* @see #getFactoryKey()
|
||||
*/
|
||||
public final void setFactoryKey(final String factoryKey) {
|
||||
this.factoryKey = factoryKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the key used to locate (lookup) the Spring BeanFactory.
|
||||
*
|
||||
* @return the key used to locate the Spring BeanFactory.
|
||||
* @see org.springframework.beans.factory.BeanFactory
|
||||
* @see org.springframework.data.gemfire.GemfireBeanFactoryLocator
|
||||
* @see #setFactoryKey(String)
|
||||
*/
|
||||
protected String getFactoryKey() {
|
||||
return factoryKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that this Declarable object has been properly configured and initialized by the Spring container
|
||||
* after GemFire has constructed this Declarable object during startup. It is recommended to call this method
|
||||
@@ -88,7 +116,7 @@ public abstract class LazyWiringDeclarableSupport implements ApplicationListener
|
||||
*/
|
||||
protected void assertInitialized() {
|
||||
Assert.state(isInitialized(), String.format(
|
||||
"This Declarable object (%1$s) has not been properly configured and initialized!",
|
||||
"This Declarable object (%1$s) has not been properly configured and initialized",
|
||||
getClass().getName()));
|
||||
}
|
||||
|
||||
@@ -104,7 +132,7 @@ public abstract class LazyWiringDeclarableSupport implements ApplicationListener
|
||||
*/
|
||||
protected void assertUninitialized() {
|
||||
Assert.state(!isInitialized(), String.format(
|
||||
"This Declarable object (%1$s) has already been configured and initialized, and is currently active!",
|
||||
"This Declarable object (%1$s) has already been configured and initialized",
|
||||
getClass().getName()));
|
||||
}
|
||||
|
||||
@@ -125,33 +153,37 @@ public abstract class LazyWiringDeclarableSupport implements ApplicationListener
|
||||
* @see org.springframework.beans.factory.wiring.BeanWiringInfo
|
||||
* @see org.springframework.beans.factory.wiring.BeanWiringInfoResolver
|
||||
*/
|
||||
/* package-private */ void doInit(final ConfigurableListableBeanFactory beanFactory, final Properties parameters) {
|
||||
BeanConfigurerSupport beanConfigurer = new BeanConfigurerSupport();
|
||||
void doInit(final BeanFactory beanFactory, final Properties parameters) {
|
||||
synchronized (this) {
|
||||
if (isNotInitialized()) {
|
||||
BeanConfigurerSupport beanConfigurer = new BeanConfigurerSupport();
|
||||
|
||||
beanConfigurer.setBeanFactory(beanFactory);
|
||||
beanConfigurer.setBeanFactory(beanFactory);
|
||||
|
||||
final String templateBeanName = parameters.getProperty(BEAN_NAME_PARAMETER);
|
||||
final String templateBeanName = parameters.getProperty(BEAN_NAME_PARAMETER);
|
||||
|
||||
if (StringUtils.hasText(templateBeanName)) {
|
||||
if (beanFactory.containsBean(templateBeanName)) {
|
||||
beanConfigurer.setBeanWiringInfoResolver(new BeanWiringInfoResolver() {
|
||||
@Override public BeanWiringInfo resolveWiringInfo(final Object beanInstance) {
|
||||
return new BeanWiringInfo(templateBeanName);
|
||||
if (StringUtils.hasText(templateBeanName)) {
|
||||
if (beanFactory.containsBean(templateBeanName)) {
|
||||
beanConfigurer.setBeanWiringInfoResolver(new BeanWiringInfoResolver() {
|
||||
@Override public BeanWiringInfo resolveWiringInfo(final Object beanInstance) {
|
||||
return new BeanWiringInfo(templateBeanName);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
throw new IllegalArgumentException(String.format(
|
||||
"No bean with name '%1$s' was found in the Spring context '%2$s'.", templateBeanName, beanFactory));
|
||||
else {
|
||||
throw new IllegalArgumentException(String.format(
|
||||
"No bean with name '%1$s' was found in the Spring context '%2$s'.", templateBeanName, beanFactory));
|
||||
}
|
||||
}
|
||||
|
||||
beanConfigurer.afterPropertiesSet();
|
||||
beanConfigurer.configureBean(this);
|
||||
beanConfigurer.destroy();
|
||||
|
||||
initialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
beanConfigurer.afterPropertiesSet();
|
||||
beanConfigurer.configureBean(this);
|
||||
beanConfigurer.destroy();
|
||||
|
||||
initialized = true;
|
||||
|
||||
doPostInit(parameters);
|
||||
}
|
||||
|
||||
@@ -161,7 +193,7 @@ public abstract class LazyWiringDeclarableSupport implements ApplicationListener
|
||||
*
|
||||
* @param parameters Properties instance containing the parameters from GemFire's configuration file
|
||||
* (e.g. cache.xml) to configure and initialize this Declarable object.
|
||||
* @see #doInit(org.springframework.beans.factory.config.ConfigurableListableBeanFactory, java.util.Properties)
|
||||
* @see #doInit(BeanFactory, Properties)
|
||||
*/
|
||||
protected void doPostInit(final Properties parameters) {
|
||||
}
|
||||
@@ -174,28 +206,60 @@ public abstract class LazyWiringDeclarableSupport implements ApplicationListener
|
||||
* Declarable as a Properties instance.
|
||||
* @throws IllegalStateException if this Declarable object has already been configured/initialized
|
||||
* by the Spring container and is currently active.
|
||||
* @see #doInit(org.springframework.beans.factory.config.ConfigurableListableBeanFactory, java.util.Properties)
|
||||
* @see #doInit(BeanFactory, Properties)
|
||||
* @see java.util.Properties
|
||||
*/
|
||||
@Override
|
||||
public final void init(final Properties parameters) {
|
||||
assertUninitialized();
|
||||
parametersReference.set(parameters);
|
||||
|
||||
try {
|
||||
doInit(locateBeanFactory(getFactoryKey()), nullSafeGetParameters());
|
||||
}
|
||||
catch (IllegalStateException ignore) {
|
||||
// the BeanFactory does not exist or has been released and or closed, so ignore
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether this Declarable object has been configured and initialized (i.e. the doInit method
|
||||
* has been called) by the Spring container.
|
||||
*
|
||||
* @return a boolean value indicating whether this Declarable object has been configured and initialized by
|
||||
* the Spring container.
|
||||
* @return a boolean value indicating whether this Declarable object has been configured and initialized
|
||||
* by the Spring container.
|
||||
* @see #assertInitialized()
|
||||
* @see #doInit(org.springframework.beans.factory.config.ConfigurableListableBeanFactory, java.util.Properties)
|
||||
* @see #doInit(BeanFactory, Properties)
|
||||
*/
|
||||
protected boolean isInitialized() {
|
||||
return initialized;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether this Declarable object has been configured and initialized (i.e. the doInit method
|
||||
* has been called) by the Spring container.
|
||||
*
|
||||
* @return a boolean value indicating whether this Declarable object has been configured and initialized
|
||||
* by the Spring container.
|
||||
* @see #doInit(BeanFactory, Properties)
|
||||
* @see #isInitialized()
|
||||
*/
|
||||
protected boolean isNotInitialized() {
|
||||
return !isInitialized();
|
||||
}
|
||||
|
||||
/**
|
||||
* Locates an existing Spring BeanFactory.
|
||||
*
|
||||
* @param factoryKey the key used to locate (lookup) the Spring BeanFactory.
|
||||
* @return a reference to the Spring BeanFactory if it exists.
|
||||
* @throws IllegalStateException if the BeanFactory has already been released or closed.
|
||||
* @see org.springframework.data.gemfire.GemfireBeanFactoryLocator
|
||||
* @see org.springframework.beans.factory.BeanFactory
|
||||
*/
|
||||
protected BeanFactory locateBeanFactory(String factoryKey) {
|
||||
return new GemfireBeanFactoryLocator().useBeanFactory(factoryKey).getFactory();
|
||||
}
|
||||
|
||||
/**
|
||||
* Null-safe operation to return the parameters passed to this Declarable object when created by GemFire from it's
|
||||
* configuration meta-data.
|
||||
@@ -216,19 +280,15 @@ public abstract class LazyWiringDeclarableSupport implements ApplicationListener
|
||||
* @param event the ContextRefreshedEvent published by the Spring ApplicationContext after it is successfully
|
||||
* created and initialized by GemFire.
|
||||
* @throws IllegalArgumentException if the ApplicationContext is not an instance of ConfigurableApplicationContext.
|
||||
* @see #doInit(org.springframework.beans.factory.config.ConfigurableListableBeanFactory, java.util.Properties)
|
||||
* @see #doInit(BeanFactory, Properties)
|
||||
* @see #nullSafeGetParameters()
|
||||
* @see org.springframework.context.ApplicationListener#onApplicationEvent(org.springframework.context.ApplicationEvent)
|
||||
* @see org.springframework.context.event.ContextRefreshedEvent
|
||||
*/
|
||||
@Override
|
||||
public final void onApplicationEvent(final ContextRefreshedEvent event) {
|
||||
Assert.isTrue(event.getApplicationContext() instanceof ConfigurableApplicationContext,
|
||||
String.format("The Spring ApplicationContext (%1$s) must be an instance of ConfigurableApplicationContext.",
|
||||
ObjectUtils.nullSafeClassName(event.getApplicationContext())));
|
||||
|
||||
doInit(((ConfigurableApplicationContext) event.getApplicationContext()).getBeanFactory(),
|
||||
nullSafeGetParameters());
|
||||
Assert.notNull(event.getApplicationContext(), "The Spring ApplicationContext must not be null");
|
||||
doInit(event.getApplicationContext(), nullSafeGetParameters());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -24,43 +24,50 @@ import org.springframework.beans.factory.wiring.BeanWiringInfo;
|
||||
import org.springframework.beans.factory.wiring.BeanWiringInfoResolver;
|
||||
|
||||
import com.gemstone.gemfire.cache.Declarable;
|
||||
import com.gemstone.gemfire.management.internal.cli.util.spring.StringUtils;
|
||||
|
||||
/**
|
||||
* Dedicated {@link Declarable} support class for wiring the declaring instance through
|
||||
* the Spring container.
|
||||
* This implementation will first look for a 'bean-name' property which will be used to
|
||||
* locate a 'template' bean definition. In case the property is not given, a bean named
|
||||
* after the class will be searched and if none is found, autowiring will be performed,
|
||||
* based on the settings defined in the Spring container.
|
||||
* Dedicated {@link Declarable} support class for wiring the declaring instance through the Spring container.
|
||||
*
|
||||
* <p>This implementation first looks for a 'bean-name' property which will be used to locate a 'template'
|
||||
* bean definition. Autowiring will be performed, based on the settings defined in the Spring container.
|
||||
*
|
||||
* @author Costin Leau
|
||||
* @author John Blum
|
||||
* @see org.springframework.beans.factory.BeanFactory
|
||||
* @see org.springframework.beans.factory.wiring.BeanConfigurerSupport
|
||||
* @see org.springframework.beans.factory.wiring.BeanWiringInfo
|
||||
* @see org.springframework.data.gemfire.DeclarableSupport
|
||||
* @see com.gemstone.gemfire.cache.Declarable
|
||||
*/
|
||||
public class WiringDeclarableSupport extends DeclarableSupport {
|
||||
|
||||
private static final String BEAN_NAME_PROP = "bean-name";
|
||||
private static final String BEAN_NAME_PROPERTY = "bean-name";
|
||||
|
||||
@Override
|
||||
protected void initInstance(Properties props) {
|
||||
BeanFactory bf = getBeanFactory();
|
||||
BeanConfigurerSupport configurer = new BeanConfigurerSupport();
|
||||
configurer.setBeanFactory(bf);
|
||||
protected void initInstance(Properties parameters) {
|
||||
BeanFactory beanFactory = getBeanFactory();
|
||||
|
||||
final String beanName = props.getProperty(BEAN_NAME_PROP);
|
||||
// key specified, search for a bean
|
||||
if (beanName != null) {
|
||||
if (!bf.containsBean(beanName)) {
|
||||
throw new IllegalArgumentException("Cannot find bean named '" + beanName + "'");
|
||||
BeanConfigurerSupport beanConfigurer = new BeanConfigurerSupport();
|
||||
beanConfigurer.setBeanFactory(beanFactory);
|
||||
|
||||
final String beanName = parameters.getProperty(BEAN_NAME_PROPERTY);
|
||||
|
||||
if (StringUtils.hasText(beanName)) {
|
||||
if (!beanFactory.containsBean(beanName)) {
|
||||
throw new IllegalArgumentException(String.format("Cannot find bean named '%1$s'", beanName));
|
||||
}
|
||||
configurer.setBeanWiringInfoResolver(new BeanWiringInfoResolver() {
|
||||
|
||||
beanConfigurer.setBeanWiringInfoResolver(new BeanWiringInfoResolver() {
|
||||
public BeanWiringInfo resolveWiringInfo(Object beanInstance) {
|
||||
return new BeanWiringInfo(beanName);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
configurer.afterPropertiesSet();
|
||||
configurer.configureBean(this);
|
||||
configurer.destroy();
|
||||
beanConfigurer.afterPropertiesSet();
|
||||
beanConfigurer.configureBean(this);
|
||||
beanConfigurer.destroy();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -56,10 +56,12 @@ import com.gemstone.gemfire.cache.Declarable;
|
||||
* @see org.springframework.context.ApplicationListener
|
||||
* @see org.springframework.context.ConfigurableApplicationContext
|
||||
* @see org.springframework.context.annotation.AnnotationConfigApplicationContext
|
||||
* @see org.springframework.context.event.ApplicationContextEvent
|
||||
* @see org.springframework.context.event.ApplicationEventMulticaster
|
||||
* @see org.springframework.context.support.ClassPathXmlApplicationContext
|
||||
* @see com.gemstone.gemfire.cache.Declarable
|
||||
* @see <a href="http://gemfire.docs.pivotal.io/latest/userguide/index.html#basic_config/the_cache/setting_cache_initializer.html">Setting Cache Initializer</a>
|
||||
* @see <a href="https://jira.springsource.org/browse/SGF-248">SGF-248</a>
|
||||
* @link http://gemfire.docs.pivotal.io/latest/userguide/index.html#basic_config/the_cache/setting_cache_initializer.html
|
||||
* @link https://jira.springsource.org/browse/SGF-248
|
||||
* @since 1.4.0
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
@@ -73,11 +75,11 @@ public class SpringContextBootstrappingInitializer implements Declarable, Applic
|
||||
|
||||
private static final ApplicationEventMulticaster applicationEventNotifier = new SimpleApplicationEventMulticaster();
|
||||
|
||||
private static final AtomicReference<ClassLoader> beanClassLoaderRef = new AtomicReference<ClassLoader>(null);
|
||||
private static final AtomicReference<ClassLoader> beanClassLoaderReference = new AtomicReference<ClassLoader>(null);
|
||||
|
||||
/* package-private */ static volatile ConfigurableApplicationContext applicationContext;
|
||||
static volatile ConfigurableApplicationContext applicationContext;
|
||||
|
||||
/* package-private */ static volatile ContextRefreshedEvent contextRefreshedEvent;
|
||||
static volatile ContextRefreshedEvent contextRefreshedEvent;
|
||||
|
||||
private static final List<Class<?>> registeredAnnotatedClasses = new CopyOnWriteArrayList<Class<?>>();
|
||||
|
||||
@@ -96,8 +98,8 @@ public class SpringContextBootstrappingInitializer implements Declarable, Applic
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the ClassLoader used by Spring ApplicationContext, created by this GemFire ("Bootstrapping") Initializer,
|
||||
* when creating bean definition classes.
|
||||
* Sets the ClassLoader used by the Spring ApplicationContext, created by this GemFire 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
|
||||
@@ -106,7 +108,7 @@ public class SpringContextBootstrappingInitializer implements Declarable, Applic
|
||||
*/
|
||||
public static void setBeanClassLoader(ClassLoader beanClassLoader) {
|
||||
if (applicationContext == null || !applicationContext.isActive()) {
|
||||
beanClassLoaderRef.set(beanClassLoader);
|
||||
beanClassLoaderReference.set(beanClassLoader);
|
||||
}
|
||||
else {
|
||||
throw new IllegalStateException("The Spring ApplicationContext has already been initialized!");
|
||||
@@ -167,7 +169,7 @@ public class SpringContextBootstrappingInitializer implements Declarable, Applic
|
||||
* @see #unregister(Class)
|
||||
*/
|
||||
public static boolean register(Class<?> annotatedClass) {
|
||||
Assert.notNull(annotatedClass, "the Spring annotated class to register must not be null");
|
||||
Assert.notNull(annotatedClass, "The Spring annotated class to register must not be null");
|
||||
return registeredAnnotatedClasses.add(annotatedClass);
|
||||
}
|
||||
|
||||
@@ -216,6 +218,14 @@ public class SpringContextBootstrappingInitializer implements Declarable, Applic
|
||||
return LogFactory.getLog(getClass());
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
private boolean isConfigurable(Collection<Class<?>> annotatedClasses, String[] basePackages,
|
||||
String[] contextConfigLocations) {
|
||||
|
||||
return !(CollectionUtils.isEmpty(annotatedClasses) && ObjectUtils.isEmpty(basePackages)
|
||||
&& ObjectUtils.isEmpty(contextConfigLocations));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates (constructs and configures) an instance of the ConfigurableApplicationContext based on either the
|
||||
* specified base packages containing @Configuration, @Component or JSR 330 annotated classes to scan, or the
|
||||
@@ -241,17 +251,12 @@ public class SpringContextBootstrappingInitializer implements Declarable, Applic
|
||||
* @see org.springframework.context.support.ClassPathXmlApplicationContext
|
||||
*/
|
||||
protected ConfigurableApplicationContext createApplicationContext(String[] basePackages, String[] configLocations) {
|
||||
if (!ObjectUtils.isEmpty(configLocations)) {
|
||||
return createApplicationContext(configLocations);
|
||||
}
|
||||
else {
|
||||
Assert.isTrue(isConfigurable(basePackages, configLocations, registeredAnnotatedClasses),
|
||||
"'basePackages', 'configLocations' or 'AnnotatedClasses' must be specified in order to"
|
||||
+ " construct and configure an instance of the ConfigurableApplicationContext");
|
||||
Assert.isTrue(isConfigurable(registeredAnnotatedClasses, basePackages, configLocations),
|
||||
"'AnnotatedClasses', 'basePackages' or 'configLocations' must be specified in order to"
|
||||
+ " construct and configure an instance of the ConfigurableApplicationContext");
|
||||
|
||||
return scanBasePackages(registerAnnotatedClasses((AnnotationConfigApplicationContext) createApplicationContext(null),
|
||||
registeredAnnotatedClasses.toArray(new Class<?>[registeredAnnotatedClasses.size()])), basePackages);
|
||||
}
|
||||
return scanBasePackages(registerAnnotatedClasses(createApplicationContext(configLocations),
|
||||
registeredAnnotatedClasses.toArray(new Class<?>[registeredAnnotatedClasses.size()])), basePackages);
|
||||
}
|
||||
|
||||
/* (non-Javadoc) - used for testing purposes only */
|
||||
@@ -272,7 +277,7 @@ public class SpringContextBootstrappingInitializer implements Declarable, Applic
|
||||
* @throws java.lang.IllegalArgumentException if the ApplicationContext reference is null!
|
||||
*/
|
||||
protected ConfigurableApplicationContext initApplicationContext(ConfigurableApplicationContext applicationContext) {
|
||||
Assert.notNull(applicationContext, "The ConfigurableApplicationContext reference must not be null!");
|
||||
Assert.notNull(applicationContext, "The ConfigurableApplicationContext reference must not be null");
|
||||
applicationContext.addApplicationListener(this);
|
||||
applicationContext.registerShutdownHook();
|
||||
return setClassLoader(applicationContext);
|
||||
@@ -288,29 +293,11 @@ public class SpringContextBootstrappingInitializer implements Declarable, Applic
|
||||
* @throws java.lang.IllegalArgumentException if the ApplicationContext reference is null!
|
||||
*/
|
||||
protected ConfigurableApplicationContext refreshApplicationContext(ConfigurableApplicationContext applicationContext) {
|
||||
Assert.notNull(applicationContext, "The ConfigurableApplicationContext reference must not be null!");
|
||||
Assert.notNull(applicationContext, "The ConfigurableApplicationContext reference must not be null");
|
||||
applicationContext.refresh();
|
||||
return applicationContext;
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
private boolean isConfigurable(String[] basePackages, String[] contextConfigLocations,
|
||||
Collection<Class<?>> annotatedClasses) {
|
||||
return !(ObjectUtils.isEmpty(basePackages) && ObjectUtils.isEmpty(contextConfigLocations)
|
||||
&& CollectionUtils.isEmpty(annotatedClasses));
|
||||
}
|
||||
|
||||
/**
|
||||
* Null-safe operation used to get the ID of the Spring ApplicationContext.
|
||||
*
|
||||
* @param applicationContext the Spring ApplicationContext from which to get the ID.
|
||||
* @return the ID of the given Spring ApplicationContext or null if the ApplicationContext reference is null.
|
||||
* @see org.springframework.context.ApplicationContext#getId()
|
||||
*/
|
||||
String nullSafeGetApplicationContextId(ApplicationContext applicationContext) {
|
||||
return (applicationContext != null ? applicationContext.getId() : null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers the given Spring annotated (@Configuration) POJO classes with the specified
|
||||
* AnnotationConfigApplicationContext.
|
||||
@@ -322,10 +309,10 @@ public class SpringContextBootstrappingInitializer implements Declarable, Applic
|
||||
* @return the given AnnotationConfigApplicationContext.
|
||||
* @see org.springframework.context.annotation.AnnotationConfigApplicationContext#register(Class[])
|
||||
*/
|
||||
AnnotationConfigApplicationContext registerAnnotatedClasses(AnnotationConfigApplicationContext applicationContext,
|
||||
ConfigurableApplicationContext registerAnnotatedClasses(ConfigurableApplicationContext applicationContext,
|
||||
Class<?>[] annotatedClasses) {
|
||||
if (!ObjectUtils.isEmpty(annotatedClasses)) {
|
||||
applicationContext.register(annotatedClasses);
|
||||
if (applicationContext instanceof AnnotationConfigApplicationContext && !ObjectUtils.isEmpty(annotatedClasses)) {
|
||||
((AnnotationConfigApplicationContext) applicationContext).register(annotatedClasses);
|
||||
}
|
||||
|
||||
return applicationContext;
|
||||
@@ -341,10 +328,10 @@ public class SpringContextBootstrappingInitializer implements Declarable, Applic
|
||||
* @return the given AnnotationConfigApplicationContext.
|
||||
* @see org.springframework.context.annotation.AnnotationConfigApplicationContext#scan(String...)
|
||||
*/
|
||||
AnnotationConfigApplicationContext scanBasePackages(AnnotationConfigApplicationContext applicationContext,
|
||||
ConfigurableApplicationContext scanBasePackages(ConfigurableApplicationContext applicationContext,
|
||||
String[] basePackages) {
|
||||
if (!ObjectUtils.isEmpty(basePackages)) {
|
||||
applicationContext.scan(basePackages);
|
||||
if (applicationContext instanceof AnnotationConfigApplicationContext && !ObjectUtils.isEmpty(basePackages)) {
|
||||
((AnnotationConfigApplicationContext) applicationContext).scan(basePackages);
|
||||
}
|
||||
|
||||
return applicationContext;
|
||||
@@ -359,7 +346,7 @@ public class SpringContextBootstrappingInitializer implements Declarable, Applic
|
||||
* @see java.lang.ClassLoader
|
||||
*/
|
||||
ConfigurableApplicationContext setClassLoader(ConfigurableApplicationContext applicationContext) {
|
||||
ClassLoader beanClassLoader = beanClassLoaderRef.get();
|
||||
ClassLoader beanClassLoader = beanClassLoaderReference.get();
|
||||
|
||||
if (applicationContext instanceof DefaultResourceLoader && beanClassLoader != null) {
|
||||
((DefaultResourceLoader) applicationContext).setClassLoader(beanClassLoader);
|
||||
@@ -368,6 +355,17 @@ public class SpringContextBootstrappingInitializer implements Declarable, Applic
|
||||
return applicationContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* Null-safe operation used to get the ID of the Spring ApplicationContext.
|
||||
*
|
||||
* @param applicationContext the Spring ApplicationContext from which to get the ID.
|
||||
* @return the ID of the given Spring ApplicationContext or null if the ApplicationContext reference is null.
|
||||
* @see org.springframework.context.ApplicationContext#getId()
|
||||
*/
|
||||
String nullSafeGetApplicationContextId(ApplicationContext applicationContext) {
|
||||
return (applicationContext != null ? applicationContext.getId() : null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes a Spring ApplicationContext with the given parameters specified with a GemFire <initializer>
|
||||
* block in cache.xml.
|
||||
@@ -409,7 +407,7 @@ public class SpringContextBootstrappingInitializer implements Declarable, Applic
|
||||
}
|
||||
}
|
||||
catch (Throwable cause) {
|
||||
String message = "Failed to bootstrap the Spring ApplicationContext!";
|
||||
String message = "Failed to bootstrap the Spring ApplicationContext";
|
||||
logger.error(message, cause);
|
||||
throw new ApplicationContextException(message, cause);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user