DefaultLifecycleProcessor properly counts dependent beans in same phase
Issue: SPR-16901
This commit is contained in:
@@ -19,6 +19,7 @@ package org.springframework.context.support;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.LinkedHashSet;
|
import java.util.LinkedHashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -162,7 +163,7 @@ public class DefaultLifecycleProcessor implements LifecycleProcessor, BeanFactor
|
|||||||
/**
|
/**
|
||||||
* Start the specified bean as part of the given set of Lifecycle beans,
|
* Start the specified bean as part of the given set of Lifecycle beans,
|
||||||
* making sure that any beans that it depends on are started first.
|
* making sure that any beans that it depends on are started first.
|
||||||
* @param lifecycleBeans Map with bean name as key and Lifecycle instance as value
|
* @param lifecycleBeans a Map with bean name as key and Lifecycle instance as value
|
||||||
* @param beanName the name of the bean to start
|
* @param beanName the name of the bean to start
|
||||||
*/
|
*/
|
||||||
private void doStart(Map<String, ? extends Lifecycle> lifecycleBeans, String beanName, boolean autoStartupOnly) {
|
private void doStart(Map<String, ? extends Lifecycle> lifecycleBeans, String beanName, boolean autoStartupOnly) {
|
||||||
@@ -175,7 +176,7 @@ public class DefaultLifecycleProcessor implements LifecycleProcessor, BeanFactor
|
|||||||
if (!bean.isRunning() &&
|
if (!bean.isRunning() &&
|
||||||
(!autoStartupOnly || !(bean instanceof SmartLifecycle) || ((SmartLifecycle) bean).isAutoStartup())) {
|
(!autoStartupOnly || !(bean instanceof SmartLifecycle) || ((SmartLifecycle) bean).isAutoStartup())) {
|
||||||
if (logger.isDebugEnabled()) {
|
if (logger.isDebugEnabled()) {
|
||||||
logger.debug("Starting bean '" + beanName + "' of type [" + bean.getClass() + "]");
|
logger.debug("Starting bean '" + beanName + "' of type [" + bean.getClass().getName() + "]");
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
bean.start();
|
bean.start();
|
||||||
@@ -214,7 +215,7 @@ public class DefaultLifecycleProcessor implements LifecycleProcessor, BeanFactor
|
|||||||
/**
|
/**
|
||||||
* Stop the specified bean as part of the given set of Lifecycle beans,
|
* Stop the specified bean as part of the given set of Lifecycle beans,
|
||||||
* making sure that any beans that depends on it are stopped first.
|
* making sure that any beans that depends on it are stopped first.
|
||||||
* @param lifecycleBeans Map with bean name as key and Lifecycle instance as value
|
* @param lifecycleBeans a Map with bean name as key and Lifecycle instance as value
|
||||||
* @param beanName the name of the bean to stop
|
* @param beanName the name of the bean to stop
|
||||||
*/
|
*/
|
||||||
private void doStop(Map<String, ? extends Lifecycle> lifecycleBeans, final String beanName,
|
private void doStop(Map<String, ? extends Lifecycle> lifecycleBeans, final String beanName,
|
||||||
@@ -230,7 +231,8 @@ public class DefaultLifecycleProcessor implements LifecycleProcessor, BeanFactor
|
|||||||
if (bean.isRunning()) {
|
if (bean.isRunning()) {
|
||||||
if (bean instanceof SmartLifecycle) {
|
if (bean instanceof SmartLifecycle) {
|
||||||
if (logger.isDebugEnabled()) {
|
if (logger.isDebugEnabled()) {
|
||||||
logger.debug("Asking bean '" + beanName + "' of type [" + bean.getClass() + "] to stop");
|
logger.debug("Asking bean '" + beanName + "' of type [" +
|
||||||
|
bean.getClass().getName() + "] to stop");
|
||||||
}
|
}
|
||||||
countDownBeanNames.add(beanName);
|
countDownBeanNames.add(beanName);
|
||||||
((SmartLifecycle) bean).stop(() -> {
|
((SmartLifecycle) bean).stop(() -> {
|
||||||
@@ -243,7 +245,8 @@ public class DefaultLifecycleProcessor implements LifecycleProcessor, BeanFactor
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (logger.isDebugEnabled()) {
|
if (logger.isDebugEnabled()) {
|
||||||
logger.debug("Stopping bean '" + beanName + "' of type [" + bean.getClass() + "]");
|
logger.debug("Stopping bean '" + beanName + "' of type [" +
|
||||||
|
bean.getClass().getName() + "]");
|
||||||
}
|
}
|
||||||
bean.stop();
|
bean.stop();
|
||||||
if (logger.isDebugEnabled()) {
|
if (logger.isDebugEnabled()) {
|
||||||
@@ -252,7 +255,7 @@ public class DefaultLifecycleProcessor implements LifecycleProcessor, BeanFactor
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (bean instanceof SmartLifecycle) {
|
else if (bean instanceof SmartLifecycle) {
|
||||||
// don't wait for beans that aren't running
|
// Don't wait for beans that aren't running...
|
||||||
latch.countDown();
|
latch.countDown();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -317,8 +320,6 @@ public class DefaultLifecycleProcessor implements LifecycleProcessor, BeanFactor
|
|||||||
*/
|
*/
|
||||||
private class LifecycleGroup {
|
private class LifecycleGroup {
|
||||||
|
|
||||||
private final List<LifecycleGroupMember> members = new ArrayList<>();
|
|
||||||
|
|
||||||
private final int phase;
|
private final int phase;
|
||||||
|
|
||||||
private final long timeout;
|
private final long timeout;
|
||||||
@@ -327,9 +328,13 @@ public class DefaultLifecycleProcessor implements LifecycleProcessor, BeanFactor
|
|||||||
|
|
||||||
private final boolean autoStartupOnly;
|
private final boolean autoStartupOnly;
|
||||||
|
|
||||||
private volatile int smartMemberCount;
|
private final List<LifecycleGroupMember> members = new ArrayList<>();
|
||||||
|
|
||||||
|
private int smartMemberCount;
|
||||||
|
|
||||||
|
public LifecycleGroup(
|
||||||
|
int phase, long timeout, Map<String, ? extends Lifecycle> lifecycleBeans, boolean autoStartupOnly) {
|
||||||
|
|
||||||
public LifecycleGroup(int phase, long timeout, Map<String, ? extends Lifecycle> lifecycleBeans, boolean autoStartupOnly) {
|
|
||||||
this.phase = phase;
|
this.phase = phase;
|
||||||
this.timeout = timeout;
|
this.timeout = timeout;
|
||||||
this.lifecycleBeans = lifecycleBeans;
|
this.lifecycleBeans = lifecycleBeans;
|
||||||
@@ -337,10 +342,10 @@ public class DefaultLifecycleProcessor implements LifecycleProcessor, BeanFactor
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void add(String name, Lifecycle bean) {
|
public void add(String name, Lifecycle bean) {
|
||||||
|
this.members.add(new LifecycleGroupMember(name, bean));
|
||||||
if (bean instanceof SmartLifecycle) {
|
if (bean instanceof SmartLifecycle) {
|
||||||
this.smartMemberCount++;
|
this.smartMemberCount++;
|
||||||
}
|
}
|
||||||
this.members.add(new LifecycleGroupMember(name, bean));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void start() {
|
public void start() {
|
||||||
@@ -352,9 +357,7 @@ public class DefaultLifecycleProcessor implements LifecycleProcessor, BeanFactor
|
|||||||
}
|
}
|
||||||
Collections.sort(this.members);
|
Collections.sort(this.members);
|
||||||
for (LifecycleGroupMember member : this.members) {
|
for (LifecycleGroupMember member : this.members) {
|
||||||
if (this.lifecycleBeans.containsKey(member.name)) {
|
doStart(this.lifecycleBeans, member.name, this.autoStartupOnly);
|
||||||
doStart(this.lifecycleBeans, member.name, this.autoStartupOnly);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -368,12 +371,13 @@ public class DefaultLifecycleProcessor implements LifecycleProcessor, BeanFactor
|
|||||||
this.members.sort(Collections.reverseOrder());
|
this.members.sort(Collections.reverseOrder());
|
||||||
CountDownLatch latch = new CountDownLatch(this.smartMemberCount);
|
CountDownLatch latch = new CountDownLatch(this.smartMemberCount);
|
||||||
Set<String> countDownBeanNames = Collections.synchronizedSet(new LinkedHashSet<>());
|
Set<String> countDownBeanNames = Collections.synchronizedSet(new LinkedHashSet<>());
|
||||||
|
Set<String> lifecycleBeanNames = new HashSet<>(this.lifecycleBeans.keySet());
|
||||||
for (LifecycleGroupMember member : this.members) {
|
for (LifecycleGroupMember member : this.members) {
|
||||||
if (this.lifecycleBeans.containsKey(member.name)) {
|
if (lifecycleBeanNames.contains(member.name)) {
|
||||||
doStop(this.lifecycleBeans, member.name, latch, countDownBeanNames);
|
doStop(this.lifecycleBeans, member.name, latch, countDownBeanNames);
|
||||||
}
|
}
|
||||||
else if (member.bean instanceof SmartLifecycle) {
|
else if (member.bean instanceof SmartLifecycle) {
|
||||||
// already removed, must have been a dependent
|
// Already removed: must have been a dependent bean from another phase
|
||||||
latch.countDown();
|
latch.countDown();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user