SmartLifecycle retrieval fix, properly taking FactoryBeans into account (SPR-6545)
This commit is contained in:
parent
a0c4d2c13c
commit
42c7be4590
|
|
@ -30,6 +30,7 @@ import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
import org.springframework.beans.factory.BeanFactory;
|
import org.springframework.beans.factory.BeanFactory;
|
||||||
import org.springframework.beans.factory.BeanFactoryAware;
|
import org.springframework.beans.factory.BeanFactoryAware;
|
||||||
|
import org.springframework.beans.factory.BeanFactoryUtils;
|
||||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||||
import org.springframework.context.Lifecycle;
|
import org.springframework.context.Lifecycle;
|
||||||
import org.springframework.context.LifecycleProcessor;
|
import org.springframework.context.LifecycleProcessor;
|
||||||
|
|
@ -216,17 +217,22 @@ public class DefaultLifecycleProcessor implements LifecycleProcessor, BeanFactor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve all applicable Lifecycle beans: all singletons that have already been created,
|
||||||
|
* as well as all SmartLifecycle beans (even if they are marked as lazy-init).
|
||||||
|
*/
|
||||||
private Map<String, Lifecycle> getLifecycleBeans() {
|
private Map<String, Lifecycle> getLifecycleBeans() {
|
||||||
Map<String, Lifecycle> beans = new LinkedHashMap<String, Lifecycle>();
|
Map<String, Lifecycle> beans = new LinkedHashMap<String, Lifecycle>();
|
||||||
Map<String, SmartLifecycle> smartLifecycles =
|
String[] beanNames = this.beanFactory.getBeanNamesForType(Lifecycle.class, false, false);
|
||||||
this.beanFactory.getBeansOfType(SmartLifecycle.class, false, true);
|
for (String beanName : beanNames) {
|
||||||
beans.putAll(smartLifecycles);
|
String beanNameToRegister = BeanFactoryUtils.transformedBeanName(beanName);
|
||||||
String[] singletonNames = this.beanFactory.getSingletonNames();
|
String beanNameToCheck = (this.beanFactory.isFactoryBean(beanNameToRegister) ?
|
||||||
for (String beanName : singletonNames) {
|
BeanFactory.FACTORY_BEAN_PREFIX + beanName : beanName);
|
||||||
if (!beans.containsKey(beanName)) {
|
if (this.beanFactory.containsSingleton(beanNameToRegister) ||
|
||||||
Object bean = this.beanFactory.getSingleton(beanName);
|
SmartLifecycle.class.isAssignableFrom(this.beanFactory.getType(beanNameToCheck))) {
|
||||||
if (bean instanceof Lifecycle && !this.equals(bean)) {
|
Lifecycle bean = this.beanFactory.getBean(beanNameToCheck, Lifecycle.class);
|
||||||
beans.put(beanName, (Lifecycle) bean);
|
if (bean != this) {
|
||||||
|
beans.put(beanNameToRegister, bean);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ import static org.junit.Assert.*;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import org.springframework.beans.DirectFieldAccessor;
|
import org.springframework.beans.DirectFieldAccessor;
|
||||||
|
import org.springframework.beans.factory.FactoryBean;
|
||||||
import org.springframework.beans.factory.config.BeanDefinition;
|
import org.springframework.beans.factory.config.BeanDefinition;
|
||||||
import org.springframework.beans.factory.support.RootBeanDefinition;
|
import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||||
import org.springframework.context.Lifecycle;
|
import org.springframework.context.Lifecycle;
|
||||||
|
|
@ -85,6 +86,19 @@ public class DefaultLifecycleProcessorTests {
|
||||||
assertFalse(bean.isRunning());
|
assertFalse(bean.isRunning());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void singleSmartLifecycleAutoStartupWithLazyInitFactoryBean() throws Exception {
|
||||||
|
StaticApplicationContext context = new StaticApplicationContext();
|
||||||
|
RootBeanDefinition bd = new RootBeanDefinition(DummySmartLifecycleFactoryBean.class);
|
||||||
|
bd.setLazyInit(true);
|
||||||
|
context.registerBeanDefinition("bean", bd);
|
||||||
|
context.refresh();
|
||||||
|
DummySmartLifecycleFactoryBean bean = context.getBean("&bean", DummySmartLifecycleFactoryBean.class);
|
||||||
|
assertTrue(bean.isRunning());
|
||||||
|
context.stop();
|
||||||
|
assertFalse(bean.isRunning());
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void singleSmartLifecycleWithoutAutoStartup() throws Exception {
|
public void singleSmartLifecycleWithoutAutoStartup() throws Exception {
|
||||||
CopyOnWriteArrayList<Lifecycle> startedBeans = new CopyOnWriteArrayList<Lifecycle>();
|
CopyOnWriteArrayList<Lifecycle> startedBeans = new CopyOnWriteArrayList<Lifecycle>();
|
||||||
|
|
@ -654,4 +668,49 @@ public class DefaultLifecycleProcessorTests {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static class DummySmartLifecycleFactoryBean implements FactoryBean, SmartLifecycle {
|
||||||
|
|
||||||
|
public boolean running = false;
|
||||||
|
|
||||||
|
DummySmartLifecycleBean bean = new DummySmartLifecycleBean();
|
||||||
|
|
||||||
|
public Object getObject() throws Exception {
|
||||||
|
return this.bean;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Class getObjectType() {
|
||||||
|
return DummySmartLifecycleBean.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isSingleton() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isAutoStartup() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void stop(Runnable callback) {
|
||||||
|
this.running = false;
|
||||||
|
callback.run();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void start() {
|
||||||
|
this.running = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void stop() {
|
||||||
|
this.running = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isRunning() {
|
||||||
|
return this.running;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getPhase() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue