SmartLifecycle beans in Lifecycle dependency graphs are only being started when isAutoStartup=true (SPR-8912)

master
Juergen Hoeller 13 years ago
parent 2fa9ef9f5a
commit 0042243a11
  1. 34
      org.springframework.context/src/main/java/org/springframework/context/support/DefaultLifecycleProcessor.java
  2. 31
      org.springframework.context/src/test/java/org/springframework/context/support/DefaultLifecycleProcessorTests.java

@ -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…
Cancel
Save