SmartLifecycle beans in Lifecycle dependency graphs are only being started when isAutoStartup=true (SPR-8912)
This commit is contained in:
parent
2fa9ef9f5a
commit
0042243a11
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
* Copyright 2002-2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -125,15 +125,15 @@ public class DefaultLifecycleProcessor implements LifecycleProcessor, BeanFactor
|
|||
Map<String, Lifecycle> lifecycleBeans = getLifecycleBeans();
|
||||
Map<Integer, LifecycleGroup> phases = new HashMap<Integer, LifecycleGroup>();
|
||||
for (Map.Entry<String, ? extends Lifecycle> entry : lifecycleBeans.entrySet()) {
|
||||
Lifecycle lifecycle = entry.getValue();
|
||||
if (!autoStartupOnly || (lifecycle instanceof SmartLifecycle && ((SmartLifecycle) lifecycle).isAutoStartup())) {
|
||||
int phase = getPhase(lifecycle);
|
||||
Lifecycle bean = entry.getValue();
|
||||
if (!autoStartupOnly || (bean instanceof SmartLifecycle && ((SmartLifecycle) bean).isAutoStartup())) {
|
||||
int phase = getPhase(bean);
|
||||
LifecycleGroup group = phases.get(phase);
|
||||
if (group == null) {
|
||||
group = new LifecycleGroup(phase, this.timeoutPerShutdownPhase, lifecycleBeans);
|
||||
group = new LifecycleGroup(phase, this.timeoutPerShutdownPhase, lifecycleBeans, autoStartupOnly);
|
||||
phases.put(phase, group);
|
||||
}
|
||||
group.add(entry.getKey(), lifecycle);
|
||||
group.add(entry.getKey(), bean);
|
||||
}
|
||||
}
|
||||
if (phases.size() > 0) {
|
||||
|
@ -151,14 +151,15 @@ public class DefaultLifecycleProcessor implements LifecycleProcessor, BeanFactor
|
|||
* @param lifecycleBeans Map with bean name as key and Lifecycle instance as value
|
||||
* @param beanName the name of the bean to start
|
||||
*/
|
||||
private void doStart(Map<String, ? extends Lifecycle> lifecycleBeans, String beanName) {
|
||||
private void doStart(Map<String, ? extends Lifecycle> lifecycleBeans, String beanName, boolean autoStartupOnly) {
|
||||
Lifecycle bean = lifecycleBeans.remove(beanName);
|
||||
if (bean != null && !this.equals(bean)) {
|
||||
String[] dependenciesForBean = this.beanFactory.getDependenciesForBean(beanName);
|
||||
for (String dependency : dependenciesForBean) {
|
||||
doStart(lifecycleBeans, dependency);
|
||||
doStart(lifecycleBeans, dependency, autoStartupOnly);
|
||||
}
|
||||
if (!bean.isRunning()) {
|
||||
if (!bean.isRunning() &&
|
||||
(!autoStartupOnly || !(bean instanceof SmartLifecycle) || ((SmartLifecycle) bean).isAutoStartup())) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Starting bean '" + beanName + "' of type [" + bean.getClass() + "]");
|
||||
}
|
||||
|
@ -179,14 +180,14 @@ public class DefaultLifecycleProcessor implements LifecycleProcessor, BeanFactor
|
|||
Map<String, Lifecycle> lifecycleBeans = getLifecycleBeans();
|
||||
Map<Integer, LifecycleGroup> phases = new HashMap<Integer, LifecycleGroup>();
|
||||
for (Map.Entry<String, Lifecycle> entry : lifecycleBeans.entrySet()) {
|
||||
Lifecycle lifecycle = entry.getValue();
|
||||
int shutdownOrder = getPhase(lifecycle);
|
||||
Lifecycle bean = entry.getValue();
|
||||
int shutdownOrder = getPhase(bean);
|
||||
LifecycleGroup group = phases.get(shutdownOrder);
|
||||
if (group == null) {
|
||||
group = new LifecycleGroup(shutdownOrder, this.timeoutPerShutdownPhase, lifecycleBeans);
|
||||
group = new LifecycleGroup(shutdownOrder, this.timeoutPerShutdownPhase, lifecycleBeans, false);
|
||||
phases.put(shutdownOrder, group);
|
||||
}
|
||||
group.add(entry.getKey(), lifecycle);
|
||||
group.add(entry.getKey(), bean);
|
||||
}
|
||||
if (phases.size() > 0) {
|
||||
List<Integer> keys = new ArrayList<Integer>(phases.keySet());
|
||||
|
@ -309,10 +310,13 @@ public class DefaultLifecycleProcessor implements LifecycleProcessor, BeanFactor
|
|||
|
||||
private final long timeout;
|
||||
|
||||
public LifecycleGroup(int phase, long timeout, Map<String, ? extends Lifecycle> lifecycleBeans) {
|
||||
private final boolean autoStartupOnly;
|
||||
|
||||
public LifecycleGroup(int phase, long timeout, Map<String, ? extends Lifecycle> lifecycleBeans, boolean autoStartupOnly) {
|
||||
this.phase = phase;
|
||||
this.timeout = timeout;
|
||||
this.lifecycleBeans = lifecycleBeans;
|
||||
this.autoStartupOnly = autoStartupOnly;
|
||||
}
|
||||
|
||||
public void add(String name, Lifecycle bean) {
|
||||
|
@ -332,7 +336,7 @@ public class DefaultLifecycleProcessor implements LifecycleProcessor, BeanFactor
|
|||
Collections.sort(this.members);
|
||||
for (LifecycleGroupMember member : this.members) {
|
||||
if (this.lifecycleBeans.containsKey(member.name)) {
|
||||
doStart(this.lifecycleBeans, member.name);
|
||||
doStart(this.lifecycleBeans, member.name, this.autoStartupOnly);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
* Copyright 2002-2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -18,7 +18,6 @@ package org.springframework.context.support;
|
|||
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.beans.DirectFieldAccessor;
|
||||
|
@ -29,6 +28,8 @@ import org.springframework.context.Lifecycle;
|
|||
import org.springframework.context.LifecycleProcessor;
|
||||
import org.springframework.context.SmartLifecycle;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* @author Mark Fisher
|
||||
* @since 3.0
|
||||
|
@ -55,7 +56,8 @@ public class DefaultLifecycleProcessorTests {
|
|||
Object contextLifecycleProcessor = new DirectFieldAccessor(context).getPropertyValue("lifecycleProcessor");
|
||||
assertNotNull(contextLifecycleProcessor);
|
||||
assertSame(bean, contextLifecycleProcessor);
|
||||
assertEquals(1000L, new DirectFieldAccessor(contextLifecycleProcessor).getPropertyValue("timeoutPerShutdownPhase"));
|
||||
assertEquals(1000L, new DirectFieldAccessor(contextLifecycleProcessor).getPropertyValue(
|
||||
"timeoutPerShutdownPhase"));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -116,6 +118,28 @@ public class DefaultLifecycleProcessorTests {
|
|||
context.stop();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void singleSmartLifecycleAutoStartupWithNonAutoStartupDependency() throws Exception {
|
||||
CopyOnWriteArrayList<Lifecycle> startedBeans = new CopyOnWriteArrayList<Lifecycle>();
|
||||
TestSmartLifecycleBean bean = TestSmartLifecycleBean.forStartupTests(1, startedBeans);
|
||||
bean.setAutoStartup(true);
|
||||
TestSmartLifecycleBean dependency = TestSmartLifecycleBean.forStartupTests(1, startedBeans);
|
||||
dependency.setAutoStartup(false);
|
||||
StaticApplicationContext context = new StaticApplicationContext();
|
||||
context.getBeanFactory().registerSingleton("bean", bean);
|
||||
context.getBeanFactory().registerSingleton("dependency", dependency);
|
||||
context.getBeanFactory().registerDependentBean("dependency", "bean");
|
||||
assertFalse(bean.isRunning());
|
||||
assertFalse(dependency.isRunning());
|
||||
context.refresh();
|
||||
assertTrue(bean.isRunning());
|
||||
assertFalse(dependency.isRunning());
|
||||
context.stop();
|
||||
assertFalse(bean.isRunning());
|
||||
assertFalse(dependency.isRunning());
|
||||
assertEquals(1, startedBeans.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void smartLifecycleGroupStartup() throws Exception {
|
||||
CopyOnWriteArrayList<Lifecycle> startedBeans = new CopyOnWriteArrayList<Lifecycle>();
|
||||
|
@ -578,7 +602,6 @@ public class DefaultLifecycleProcessorTests {
|
|||
}
|
||||
this.running = false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue