@ -33,16 +33,157 @@ import org.springframework.context.SmartLifecycle;
* /
* /
public class DefaultLifecycleProcessorTests {
public class DefaultLifecycleProcessorTests {
@Test
public void singleSmartLifecycleAutoStartup ( ) throws Exception {
CopyOnWriteArrayList < Lifecycle > startedBeans = new CopyOnWriteArrayList < Lifecycle > ( ) ;
TestSmartLifecycleBean bean = TestSmartLifecycleBean . forStartupTests ( 1 , startedBeans ) ;
bean . setAutoStartup ( true ) ;
StaticApplicationContext context = new StaticApplicationContext ( ) ;
context . getBeanFactory ( ) . registerSingleton ( "bean" , bean ) ;
assertFalse ( bean . isRunning ( ) ) ;
context . refresh ( ) ;
assertTrue ( bean . isRunning ( ) ) ;
context . stop ( ) ;
assertFalse ( bean . isRunning ( ) ) ;
assertEquals ( 1 , startedBeans . size ( ) ) ;
}
@Test
public void singleSmartLifecycleWithoutAutoStartup ( ) throws Exception {
CopyOnWriteArrayList < Lifecycle > startedBeans = new CopyOnWriteArrayList < Lifecycle > ( ) ;
TestSmartLifecycleBean bean = TestSmartLifecycleBean . forStartupTests ( 1 , startedBeans ) ;
bean . setAutoStartup ( false ) ;
StaticApplicationContext context = new StaticApplicationContext ( ) ;
context . getBeanFactory ( ) . registerSingleton ( "bean" , bean ) ;
assertFalse ( bean . isRunning ( ) ) ;
context . refresh ( ) ;
assertFalse ( bean . isRunning ( ) ) ;
assertEquals ( 0 , startedBeans . size ( ) ) ;
context . start ( ) ;
assertTrue ( bean . isRunning ( ) ) ;
assertEquals ( 1 , startedBeans . size ( ) ) ;
context . stop ( ) ;
}
@Test
public void smartLifecycleGroupStartup ( ) throws Exception {
CopyOnWriteArrayList < Lifecycle > startedBeans = new CopyOnWriteArrayList < Lifecycle > ( ) ;
TestSmartLifecycleBean beanMin = TestSmartLifecycleBean . forStartupTests ( Integer . MIN_VALUE , startedBeans ) ;
TestSmartLifecycleBean bean1 = TestSmartLifecycleBean . forStartupTests ( 1 , startedBeans ) ;
TestSmartLifecycleBean bean2 = TestSmartLifecycleBean . forStartupTests ( 2 , startedBeans ) ;
TestSmartLifecycleBean bean3 = TestSmartLifecycleBean . forStartupTests ( 3 , startedBeans ) ;
TestSmartLifecycleBean beanMax = TestSmartLifecycleBean . forStartupTests ( Integer . MAX_VALUE , startedBeans ) ;
StaticApplicationContext context = new StaticApplicationContext ( ) ;
context . getBeanFactory ( ) . registerSingleton ( "bean3" , bean3 ) ;
context . getBeanFactory ( ) . registerSingleton ( "beanMin" , beanMin ) ;
context . getBeanFactory ( ) . registerSingleton ( "bean2" , bean2 ) ;
context . getBeanFactory ( ) . registerSingleton ( "beanMax" , beanMax ) ;
context . getBeanFactory ( ) . registerSingleton ( "bean1" , bean1 ) ;
assertFalse ( beanMin . isRunning ( ) ) ;
assertFalse ( bean1 . isRunning ( ) ) ;
assertFalse ( bean2 . isRunning ( ) ) ;
assertFalse ( bean3 . isRunning ( ) ) ;
assertFalse ( beanMax . isRunning ( ) ) ;
context . refresh ( ) ;
assertTrue ( beanMin . isRunning ( ) ) ;
assertTrue ( bean1 . isRunning ( ) ) ;
assertTrue ( bean2 . isRunning ( ) ) ;
assertTrue ( bean3 . isRunning ( ) ) ;
assertTrue ( beanMax . isRunning ( ) ) ;
context . stop ( ) ;
assertEquals ( 5 , startedBeans . size ( ) ) ;
assertEquals ( Integer . MIN_VALUE , getPhase ( startedBeans . get ( 0 ) ) ) ;
assertEquals ( 1 , getPhase ( startedBeans . get ( 1 ) ) ) ;
assertEquals ( 2 , getPhase ( startedBeans . get ( 2 ) ) ) ;
assertEquals ( 3 , getPhase ( startedBeans . get ( 3 ) ) ) ;
assertEquals ( Integer . MAX_VALUE , getPhase ( startedBeans . get ( 4 ) ) ) ;
}
@Test
public void contextRefreshThenStartWithMixedBeans ( ) throws Exception {
CopyOnWriteArrayList < Lifecycle > startedBeans = new CopyOnWriteArrayList < Lifecycle > ( ) ;
TestLifecycleBean simpleBean1 = TestLifecycleBean . forStartupTests ( startedBeans ) ;
TestLifecycleBean simpleBean2 = TestLifecycleBean . forStartupTests ( startedBeans ) ;
TestSmartLifecycleBean smartBean1 = TestSmartLifecycleBean . forStartupTests ( 5 , startedBeans ) ;
TestSmartLifecycleBean smartBean2 = TestSmartLifecycleBean . forStartupTests ( - 3 , startedBeans ) ;
StaticApplicationContext context = new StaticApplicationContext ( ) ;
context . getBeanFactory ( ) . registerSingleton ( "simpleBean1" , simpleBean1 ) ;
context . getBeanFactory ( ) . registerSingleton ( "smartBean1" , smartBean1 ) ;
context . getBeanFactory ( ) . registerSingleton ( "simpleBean2" , simpleBean2 ) ;
context . getBeanFactory ( ) . registerSingleton ( "smartBean2" , smartBean2 ) ;
assertFalse ( simpleBean1 . isRunning ( ) ) ;
assertFalse ( simpleBean2 . isRunning ( ) ) ;
assertFalse ( smartBean1 . isRunning ( ) ) ;
assertFalse ( smartBean2 . isRunning ( ) ) ;
context . refresh ( ) ;
assertTrue ( smartBean1 . isRunning ( ) ) ;
assertTrue ( smartBean2 . isRunning ( ) ) ;
assertFalse ( simpleBean1 . isRunning ( ) ) ;
assertFalse ( simpleBean2 . isRunning ( ) ) ;
assertEquals ( 2 , startedBeans . size ( ) ) ;
assertEquals ( - 3 , getPhase ( startedBeans . get ( 0 ) ) ) ;
assertEquals ( 5 , getPhase ( startedBeans . get ( 1 ) ) ) ;
context . start ( ) ;
assertTrue ( smartBean1 . isRunning ( ) ) ;
assertTrue ( smartBean2 . isRunning ( ) ) ;
assertTrue ( simpleBean1 . isRunning ( ) ) ;
assertTrue ( simpleBean2 . isRunning ( ) ) ;
assertEquals ( 4 , startedBeans . size ( ) ) ;
assertEquals ( 0 , getPhase ( startedBeans . get ( 2 ) ) ) ;
assertEquals ( 0 , getPhase ( startedBeans . get ( 3 ) ) ) ;
}
@Test
public void contextRefreshThenStopAndRestartWithMixedBeans ( ) throws Exception {
CopyOnWriteArrayList < Lifecycle > startedBeans = new CopyOnWriteArrayList < Lifecycle > ( ) ;
TestLifecycleBean simpleBean1 = TestLifecycleBean . forStartupTests ( startedBeans ) ;
TestLifecycleBean simpleBean2 = TestLifecycleBean . forStartupTests ( startedBeans ) ;
TestSmartLifecycleBean smartBean1 = TestSmartLifecycleBean . forStartupTests ( 5 , startedBeans ) ;
TestSmartLifecycleBean smartBean2 = TestSmartLifecycleBean . forStartupTests ( - 3 , startedBeans ) ;
StaticApplicationContext context = new StaticApplicationContext ( ) ;
context . getBeanFactory ( ) . registerSingleton ( "simpleBean1" , simpleBean1 ) ;
context . getBeanFactory ( ) . registerSingleton ( "smartBean1" , smartBean1 ) ;
context . getBeanFactory ( ) . registerSingleton ( "simpleBean2" , simpleBean2 ) ;
context . getBeanFactory ( ) . registerSingleton ( "smartBean2" , smartBean2 ) ;
assertFalse ( simpleBean1 . isRunning ( ) ) ;
assertFalse ( simpleBean2 . isRunning ( ) ) ;
assertFalse ( smartBean1 . isRunning ( ) ) ;
assertFalse ( smartBean2 . isRunning ( ) ) ;
context . refresh ( ) ;
assertTrue ( smartBean1 . isRunning ( ) ) ;
assertTrue ( smartBean2 . isRunning ( ) ) ;
assertFalse ( simpleBean1 . isRunning ( ) ) ;
assertFalse ( simpleBean2 . isRunning ( ) ) ;
assertEquals ( 2 , startedBeans . size ( ) ) ;
assertEquals ( - 3 , getPhase ( startedBeans . get ( 0 ) ) ) ;
assertEquals ( 5 , getPhase ( startedBeans . get ( 1 ) ) ) ;
context . stop ( ) ;
assertFalse ( simpleBean1 . isRunning ( ) ) ;
assertFalse ( simpleBean2 . isRunning ( ) ) ;
assertFalse ( smartBean1 . isRunning ( ) ) ;
assertFalse ( smartBean2 . isRunning ( ) ) ;
context . start ( ) ;
assertTrue ( smartBean1 . isRunning ( ) ) ;
assertTrue ( smartBean2 . isRunning ( ) ) ;
assertTrue ( simpleBean1 . isRunning ( ) ) ;
assertTrue ( simpleBean2 . isRunning ( ) ) ;
assertEquals ( 6 , startedBeans . size ( ) ) ;
assertEquals ( - 3 , getPhase ( startedBeans . get ( 2 ) ) ) ;
assertEquals ( 0 , getPhase ( startedBeans . get ( 3 ) ) ) ;
assertEquals ( 0 , getPhase ( startedBeans . get ( 4 ) ) ) ;
assertEquals ( 5 , getPhase ( startedBeans . get ( 5 ) ) ) ;
}
@Test
@Test
public void smartLifecycleGroupShutdown ( ) throws Exception {
public void smartLifecycleGroupShutdown ( ) throws Exception {
CopyOnWriteArrayList < Lifecycle > stoppedBeans = new CopyOnWriteArrayList < Lifecycle > ( ) ;
CopyOnWriteArrayList < Lifecycle > stoppedBeans = new CopyOnWriteArrayList < Lifecycle > ( ) ;
TestSmartLifecycleBean bean1 = new TestSmartLifecycleBean ( 1 , 300 , stoppedBeans ) ;
TestSmartLifecycleBean bean1 = TestSmartLifecycleBean . forShutdownTests ( 1 , 300 , stoppedBeans ) ;
TestSmartLifecycleBean bean2 = new TestSmartLifecycleBean ( 3 , 100 , stoppedBeans ) ;
TestSmartLifecycleBean bean2 = TestSmartLifecycleBean . forShutdownTests ( 3 , 100 , stoppedBeans ) ;
TestSmartLifecycleBean bean3 = new TestSmartLifecycleBean ( 1 , 600 , stoppedBeans ) ;
TestSmartLifecycleBean bean3 = TestSmartLifecycleBean . forShutdownTests ( 1 , 600 , stoppedBeans ) ;
TestSmartLifecycleBean bean4 = new TestSmartLifecycleBean ( 2 , 400 , stoppedBeans ) ;
TestSmartLifecycleBean bean4 = TestSmartLifecycleBean . forShutdownTests ( 2 , 400 , stoppedBeans ) ;
TestSmartLifecycleBean bean5 = new TestSmartLifecycleBean ( 2 , 700 , stoppedBeans ) ;
TestSmartLifecycleBean bean5 = TestSmartLifecycleBean . forShutdownTests ( 2 , 700 , stoppedBeans ) ;
TestSmartLifecycleBean bean6 = new TestSmartLifecycleBean ( Integer . MAX_VALUE , 200 , stoppedBeans ) ;
TestSmartLifecycleBean bean6 = TestSmartLifecycleBean . forShutdownTests ( Integer . MAX_VALUE , 200 , stoppedBeans ) ;
TestSmartLifecycleBean bean7 = new TestSmartLifecycleBean ( 3 , 200 , stoppedBeans ) ;
TestSmartLifecycleBean bean7 = TestSmartLifecycleBean . forShutdownTests ( 3 , 200 , stoppedBeans ) ;
StaticApplicationContext context = new StaticApplicationContext ( ) ;
StaticApplicationContext context = new StaticApplicationContext ( ) ;
context . getBeanFactory ( ) . registerSingleton ( "bean1" , bean1 ) ;
context . getBeanFactory ( ) . registerSingleton ( "bean1" , bean1 ) ;
context . getBeanFactory ( ) . registerSingleton ( "bean2" , bean2 ) ;
context . getBeanFactory ( ) . registerSingleton ( "bean2" , bean2 ) ;
@ -53,19 +194,19 @@ public class DefaultLifecycleProcessorTests {
context . getBeanFactory ( ) . registerSingleton ( "bean7" , bean7 ) ;
context . getBeanFactory ( ) . registerSingleton ( "bean7" , bean7 ) ;
context . refresh ( ) ;
context . refresh ( ) ;
context . stop ( ) ;
context . stop ( ) ;
assertEquals ( 1 , getShutdownOrder ( stoppedBeans . get ( 0 ) ) ) ;
assertEquals ( Integer . MAX_VALUE , getPhase ( stoppedBeans . get ( 0 ) ) ) ;
assertEquals ( 1 , getShutdownOrder ( stoppedBeans . get ( 1 ) ) ) ;
assertEquals ( 3 , getPhase ( stoppedBeans . get ( 1 ) ) ) ;
assertEquals ( 2 , getShutdownOrder ( stoppedBeans . get ( 2 ) ) ) ;
assertEquals ( 3 , getPhase ( stoppedBeans . get ( 2 ) ) ) ;
assertEquals ( 2 , getShutdownOrder ( stoppedBeans . get ( 3 ) ) ) ;
assertEquals ( 2 , getPhase ( stoppedBeans . get ( 3 ) ) ) ;
assertEquals ( 3 , getShutdownOrder ( stoppedBeans . get ( 4 ) ) ) ;
assertEquals ( 2 , getPhase ( stoppedBeans . get ( 4 ) ) ) ;
assertEquals ( 3 , getShutdownOrder ( stoppedBeans . get ( 5 ) ) ) ;
assertEquals ( 1 , getPhase ( stoppedBeans . get ( 5 ) ) ) ;
assertEquals ( Integer . MAX_VALUE , getShutdownOrder ( stoppedBeans . get ( 6 ) ) ) ;
assertEquals ( 1 , getPhase ( stoppedBeans . get ( 6 ) ) ) ;
}
}
@Test
@Test
public void singleSmartLifecycleShutdown ( ) throws Exception {
public void singleSmartLifecycleShutdown ( ) throws Exception {
CopyOnWriteArrayList < Lifecycle > stoppedBeans = new CopyOnWriteArrayList < Lifecycle > ( ) ;
CopyOnWriteArrayList < Lifecycle > stoppedBeans = new CopyOnWriteArrayList < Lifecycle > ( ) ;
TestSmartLifecycleBean bean = new TestSmartLifecycleBean ( 99 , 300 , stoppedBeans ) ;
TestSmartLifecycleBean bean = TestSmartLifecycleBean . forShutdownTests ( 99 , 300 , stoppedBeans ) ;
StaticApplicationContext context = new StaticApplicationContext ( ) ;
StaticApplicationContext context = new StaticApplicationContext ( ) ;
context . getBeanFactory ( ) . registerSingleton ( "bean" , bean ) ;
context . getBeanFactory ( ) . registerSingleton ( "bean" , bean ) ;
context . refresh ( ) ;
context . refresh ( ) ;
@ -79,7 +220,7 @@ public class DefaultLifecycleProcessorTests {
@Test
@Test
public void singleLifecycleShutdown ( ) throws Exception {
public void singleLifecycleShutdown ( ) throws Exception {
CopyOnWriteArrayList < Lifecycle > stoppedBeans = new CopyOnWriteArrayList < Lifecycle > ( ) ;
CopyOnWriteArrayList < Lifecycle > stoppedBeans = new CopyOnWriteArrayList < Lifecycle > ( ) ;
Lifecycle bean = new TestLifecycleBean ( stoppedBeans ) ;
Lifecycle bean = new TestLifecycleBean ( null , stoppedBeans ) ;
StaticApplicationContext context = new StaticApplicationContext ( ) ;
StaticApplicationContext context = new StaticApplicationContext ( ) ;
context . getBeanFactory ( ) . registerSingleton ( "bean" , bean ) ;
context . getBeanFactory ( ) . registerSingleton ( "bean" , bean ) ;
context . refresh ( ) ;
context . refresh ( ) ;
@ -95,120 +236,277 @@ public class DefaultLifecycleProcessorTests {
@Test
@Test
public void mixedShutdown ( ) throws Exception {
public void mixedShutdown ( ) throws Exception {
CopyOnWriteArrayList < Lifecycle > stoppedBeans = new CopyOnWriteArrayList < Lifecycle > ( ) ;
CopyOnWriteArrayList < Lifecycle > stoppedBeans = new CopyOnWriteArrayList < Lifecycle > ( ) ;
Lifecycle bean1 = new TestLifecycleBean ( stoppedBeans ) ;
Lifecycle bean1 = TestLifecycleBean . forShutdownTests ( stoppedBeans ) ;
Lifecycle bean2 = new TestSmartLifecycleBean ( 500 , 200 , stoppedBeans ) ;
Lifecycle bean2 = TestSmartLifecycleBean . forShutdownTests ( 500 , 200 , stoppedBeans ) ;
Lifecycle bean3 = new TestSmartLifecycleBean ( Integer . MAX_VALUE , 100 , stoppedBeans ) ;
Lifecycle bean3 = TestSmartLifecycleBean . forShutdownTests ( Integer . MAX_VALUE , 100 , stoppedBeans ) ;
Lifecycle bean4 = new TestLifecycleBean ( stoppedBeans ) ;
Lifecycle bean4 = TestLifecycleBean . forShutdownTests ( stoppedBeans ) ;
Lifecycle bean5 = new TestSmartLifecycleBean ( 1 , 200 , stoppedBeans ) ;
Lifecycle bean5 = TestSmartLifecycleBean . forShutdownTests ( 1 , 200 , stoppedBeans ) ;
Lifecycle bean6 = TestSmartLifecycleBean . forShutdownTests ( - 1 , 100 , stoppedBeans ) ;
Lifecycle bean7 = TestSmartLifecycleBean . forShutdownTests ( Integer . MIN_VALUE , 300 , stoppedBeans ) ;
StaticApplicationContext context = new StaticApplicationContext ( ) ;
StaticApplicationContext context = new StaticApplicationContext ( ) ;
context . getBeanFactory ( ) . registerSingleton ( "bean1" , bean1 ) ;
context . getBeanFactory ( ) . registerSingleton ( "bean1" , bean1 ) ;
context . getBeanFactory ( ) . registerSingleton ( "bean2" , bean2 ) ;
context . getBeanFactory ( ) . registerSingleton ( "bean2" , bean2 ) ;
context . getBeanFactory ( ) . registerSingleton ( "bean3" , bean3 ) ;
context . getBeanFactory ( ) . registerSingleton ( "bean3" , bean3 ) ;
context . getBeanFactory ( ) . registerSingleton ( "bean4" , bean4 ) ;
context . getBeanFactory ( ) . registerSingleton ( "bean4" , bean4 ) ;
context . getBeanFactory ( ) . registerSingleton ( "bean5" , bean5 ) ;
context . getBeanFactory ( ) . registerSingleton ( "bean5" , bean5 ) ;
context . getBeanFactory ( ) . registerSingleton ( "bean6" , bean6 ) ;
context . getBeanFactory ( ) . registerSingleton ( "bean7" , bean7 ) ;
context . refresh ( ) ;
context . refresh ( ) ;
assertTrue ( bean2 . isRunning ( ) ) ;
assertTrue ( bean3 . isRunning ( ) ) ;
assertTrue ( bean5 . isRunning ( ) ) ;
assertTrue ( bean6 . isRunning ( ) ) ;
assertTrue ( bean7 . isRunning ( ) ) ;
assertFalse ( bean1 . isRunning ( ) ) ;
assertFalse ( bean1 . isRunning ( ) ) ;
assertFalse ( bean4 . isRunning ( ) ) ;
assertFalse ( bean4 . isRunning ( ) ) ;
bean1 . start ( ) ;
bean1 . start ( ) ;
bean4 . start ( ) ;
bean4 . start ( ) ;
assertTrue ( bean1 . isRunning ( ) ) ;
assertTrue ( bean1 . isRunning ( ) ) ;
assertTrue ( bean2 . isRunning ( ) ) ;
assertTrue ( bean3 . isRunning ( ) ) ;
assertTrue ( bean4 . isRunning ( ) ) ;
assertTrue ( bean4 . isRunning ( ) ) ;
assertTrue ( bean5 . isRunning ( ) ) ;
context . stop ( ) ;
context . stop ( ) ;
assertFalse ( bean1 . isRunning ( ) ) ;
assertFalse ( bean1 . isRunning ( ) ) ;
assertFalse ( bean2 . isRunning ( ) ) ;
assertFalse ( bean2 . isRunning ( ) ) ;
assertFalse ( bean3 . isRunning ( ) ) ;
assertFalse ( bean3 . isRunning ( ) ) ;
assertFalse ( bean4 . isRunning ( ) ) ;
assertFalse ( bean4 . isRunning ( ) ) ;
assertFalse ( bean5 . isRunning ( ) ) ;
assertFalse ( bean5 . isRunning ( ) ) ;
assertEquals ( 5 , stoppedBeans . size ( ) ) ;
assertFalse ( bean6 . isRunning ( ) ) ;
assertEquals ( 1 , getShutdownOrder ( stoppedBeans . get ( 0 ) ) ) ;
assertFalse ( bean7 . isRunning ( ) ) ;
assertEquals ( 500 , getShutdownOrder ( stoppedBeans . get ( 1 ) ) ) ;
assertEquals ( 7 , stoppedBeans . size ( ) ) ;
assertEquals ( Integer . MAX_VALUE , getShutdownOrder ( stoppedBeans . get ( 2 ) ) ) ;
assertEquals ( Integer . MAX_VALUE , getPhase ( stoppedBeans . get ( 0 ) ) ) ;
assertEquals ( Integer . MAX_VALUE , getShutdownOrder ( stoppedBeans . get ( 3 ) ) ) ;
assertEquals ( 500 , getPhase ( stoppedBeans . get ( 1 ) ) ) ;
assertEquals ( Integer . MAX_VALUE , getShutdownOrder ( stoppedBeans . get ( 4 ) ) ) ;
assertEquals ( 1 , getPhase ( stoppedBeans . get ( 2 ) ) ) ;
assertEquals ( 0 , getPhase ( stoppedBeans . get ( 3 ) ) ) ;
assertEquals ( 0 , getPhase ( stoppedBeans . get ( 4 ) ) ) ;
assertEquals ( - 1 , getPhase ( stoppedBeans . get ( 5 ) ) ) ;
assertEquals ( Integer . MIN_VALUE , getPhase ( stoppedBeans . get ( 6 ) ) ) ;
}
}
@Test
@Test
public void dependantShutdownFirstEvenIfItsOrderIsHigher ( ) throws Exception {
public void dependencyStartedFirstEvenIfItsPhaseIsHigher ( ) throws Exception {
CopyOnWriteArrayList < Lifecycle > startedBeans = new CopyOnWriteArrayList < Lifecycle > ( ) ;
TestSmartLifecycleBean beanMin = TestSmartLifecycleBean . forStartupTests ( Integer . MIN_VALUE , startedBeans ) ;
TestSmartLifecycleBean bean2 = TestSmartLifecycleBean . forStartupTests ( 2 , startedBeans ) ;
TestSmartLifecycleBean bean99 = TestSmartLifecycleBean . forStartupTests ( 99 , startedBeans ) ;
TestSmartLifecycleBean beanMax = TestSmartLifecycleBean . forStartupTests ( Integer . MAX_VALUE , startedBeans ) ;
StaticApplicationContext context = new StaticApplicationContext ( ) ;
context . getBeanFactory ( ) . registerSingleton ( "beanMin" , beanMin ) ;
context . getBeanFactory ( ) . registerSingleton ( "bean2" , bean2 ) ;
context . getBeanFactory ( ) . registerSingleton ( "bean99" , bean99 ) ;
context . getBeanFactory ( ) . registerSingleton ( "beanMax" , beanMax ) ;
context . getBeanFactory ( ) . registerDependentBean ( "bean99" , "bean2" ) ;
context . refresh ( ) ;
assertTrue ( beanMin . isRunning ( ) ) ;
assertTrue ( bean2 . isRunning ( ) ) ;
assertTrue ( bean99 . isRunning ( ) ) ;
assertTrue ( beanMax . isRunning ( ) ) ;
assertEquals ( 4 , startedBeans . size ( ) ) ;
assertEquals ( Integer . MIN_VALUE , getPhase ( startedBeans . get ( 0 ) ) ) ;
assertEquals ( 99 , getPhase ( startedBeans . get ( 1 ) ) ) ;
assertEquals ( bean99 , startedBeans . get ( 1 ) ) ;
assertEquals ( 2 , getPhase ( startedBeans . get ( 2 ) ) ) ;
assertEquals ( bean2 , startedBeans . get ( 2 ) ) ;
assertEquals ( Integer . MAX_VALUE , getPhase ( startedBeans . get ( 3 ) ) ) ;
context . stop ( ) ;
}
@Test
public void dependentShutdownFirstEvenIfItsPhaseIsLower ( ) throws Exception {
CopyOnWriteArrayList < Lifecycle > stoppedBeans = new CopyOnWriteArrayList < Lifecycle > ( ) ;
CopyOnWriteArrayList < Lifecycle > stoppedBeans = new CopyOnWriteArrayList < Lifecycle > ( ) ;
TestSmartLifecycleBean bean1 = new TestSmartLifecycleBean ( 1 , 200 , stoppedBeans ) ;
TestSmartLifecycleBean beanMin = TestSmartLifecycleBean . forShutdownTests ( Integer . MIN_VALUE , 100 , stoppedBeans ) ;
TestSmartLifecycleBean bean99 = new TestSmartLifecycleBean ( 99 , 100 , stoppedBeans ) ;
TestSmartLifecycleBean bean1 = TestSmartLifecycleBean . forShutdownTests ( 1 , 200 , stoppedBeans ) ;
TestSmartLifecycleBean bean2 = new TestSmartLifecycleBean ( 2 , 300 , stoppedBeans ) ;
TestSmartLifecycleBean bean99 = TestSmartLifecycleBean . forShutdownTests ( 99 , 100 , stoppedBeans ) ;
TestSmartLifecycleBean bean7 = new TestSmartLifecycleBean ( 7 , 400 , stoppedBeans ) ;
TestSmartLifecycleBean bean2 = TestSmartLifecycleBean . forShutdownTests ( 2 , 300 , stoppedBeans ) ;
TestSmartLifecycleBean beanLast = new TestSmartLifecycleBean ( Integer . MAX_VALUE , 400 , stoppedBeans ) ;
TestSmartLifecycleBean bean7 = TestSmartLifecycleBean . forShutdownTests ( 7 , 400 , stoppedBeans ) ;
TestSmartLifecycleBean beanMax = TestSmartLifecycleBean . forShutdownTests ( Integer . MAX_VALUE , 400 , stoppedBeans ) ;
StaticApplicationContext context = new StaticApplicationContext ( ) ;
StaticApplicationContext context = new StaticApplicationContext ( ) ;
context . getBeanFactory ( ) . registerSingleton ( "beanMin" , beanMin ) ;
context . getBeanFactory ( ) . registerSingleton ( "bean1" , bean1 ) ;
context . getBeanFactory ( ) . registerSingleton ( "bean1" , bean1 ) ;
context . getBeanFactory ( ) . registerSingleton ( "bean2" , bean2 ) ;
context . getBeanFactory ( ) . registerSingleton ( "bean2" , bean2 ) ;
context . getBeanFactory ( ) . registerSingleton ( "bean7" , bean7 ) ;
context . getBeanFactory ( ) . registerSingleton ( "bean7" , bean7 ) ;
context . getBeanFactory ( ) . registerSingleton ( "bean99" , bean99 ) ;
context . getBeanFactory ( ) . registerSingleton ( "bean99" , bean99 ) ;
context . getBeanFactory ( ) . registerSingleton ( "beanLast" , beanLast ) ;
context . getBeanFactory ( ) . registerSingleton ( "beanMax" , beanMax ) ;
context . getBeanFactory ( ) . registerDependentBean ( "bean2" , "bean99" ) ;
context . getBeanFactory ( ) . registerDependentBean ( "bean99" , "bean2 " ) ;
context . refresh ( ) ;
context . refresh ( ) ;
assertTrue ( beanMin . isRunning ( ) ) ;
assertTrue ( bean1 . isRunning ( ) ) ;
assertTrue ( bean1 . isRunning ( ) ) ;
assertTrue ( bean2 . isRunning ( ) ) ;
assertTrue ( bean7 . isRunning ( ) ) ;
assertTrue ( bean7 . isRunning ( ) ) ;
assertTrue ( bean99 . isRunning ( ) ) ;
assertTrue ( bean99 . isRunning ( ) ) ;
assertTrue ( beanMax . isRunning ( ) ) ;
context . stop ( ) ;
context . stop ( ) ;
assertFalse ( beanMin . isRunning ( ) ) ;
assertFalse ( bean1 . isRunning ( ) ) ;
assertFalse ( bean1 . isRunning ( ) ) ;
assertFalse ( bean2 . isRunning ( ) ) ;
assertFalse ( bean7 . isRunning ( ) ) ;
assertFalse ( bean7 . isRunning ( ) ) ;
assertFalse ( bean99 . isRunning ( ) ) ;
assertFalse ( bean99 . isRunning ( ) ) ;
assertEquals ( 5 , stoppedBeans . size ( ) ) ;
assertFalse ( beanMax . isRunning ( ) ) ;
assertEquals ( 1 , getShutdownOrder ( stoppedBeans . get ( 0 ) ) ) ;
assertEquals ( 6 , stoppedBeans . size ( ) ) ;
assertEquals ( 99 , getShutdownOrder ( stoppedBeans . get ( 1 ) ) ) ;
assertEquals ( Integer . MAX_VALUE , getPhase ( stoppedBeans . get ( 0 ) ) ) ;
assertEquals ( 2 , getShutdownOrder ( stoppedBeans . get ( 2 ) ) ) ;
assertEquals ( 2 , getPhase ( stoppedBeans . get ( 1 ) ) ) ;
assertEquals ( 7 , getShutdownOrder ( stoppedBeans . get ( 3 ) ) ) ;
assertEquals ( bean2 , stoppedBeans . get ( 1 ) ) ;
assertEquals ( Integer . MAX_VALUE , getShutdownOrder ( stoppedBeans . get ( 4 ) ) ) ;
assertEquals ( 99 , getPhase ( stoppedBeans . get ( 2 ) ) ) ;
assertEquals ( bean99 , stoppedBeans . get ( 2 ) ) ;
assertEquals ( 7 , getPhase ( stoppedBeans . get ( 3 ) ) ) ;
assertEquals ( 1 , getPhase ( stoppedBeans . get ( 4 ) ) ) ;
assertEquals ( Integer . MIN_VALUE , getPhase ( stoppedBeans . get ( 5 ) ) ) ;
}
@Test
public void dependencyStartedFirstAndIsSmartLifecycle ( ) throws Exception {
CopyOnWriteArrayList < Lifecycle > startedBeans = new CopyOnWriteArrayList < Lifecycle > ( ) ;
TestSmartLifecycleBean beanNegative = TestSmartLifecycleBean . forStartupTests ( - 99 , startedBeans ) ;
TestSmartLifecycleBean bean99 = TestSmartLifecycleBean . forStartupTests ( 99 , startedBeans ) ;
TestSmartLifecycleBean bean7 = TestSmartLifecycleBean . forStartupTests ( 7 , startedBeans ) ;
TestLifecycleBean simpleBean = TestLifecycleBean . forStartupTests ( startedBeans ) ;
StaticApplicationContext context = new StaticApplicationContext ( ) ;
context . getBeanFactory ( ) . registerSingleton ( "beanNegative" , beanNegative ) ;
context . getBeanFactory ( ) . registerSingleton ( "bean7" , bean7 ) ;
context . getBeanFactory ( ) . registerSingleton ( "bean99" , bean99 ) ;
context . getBeanFactory ( ) . registerSingleton ( "simpleBean" , simpleBean ) ;
context . getBeanFactory ( ) . registerDependentBean ( "bean7" , "simpleBean" ) ;
context . refresh ( ) ;
context . stop ( ) ;
startedBeans . clear ( ) ;
// clean start so that simpleBean is included
context . start ( ) ;
assertTrue ( beanNegative . isRunning ( ) ) ;
assertTrue ( bean99 . isRunning ( ) ) ;
assertTrue ( bean7 . isRunning ( ) ) ;
assertTrue ( simpleBean . isRunning ( ) ) ;
assertEquals ( 4 , startedBeans . size ( ) ) ;
assertEquals ( - 99 , getPhase ( startedBeans . get ( 0 ) ) ) ;
assertEquals ( 7 , getPhase ( startedBeans . get ( 1 ) ) ) ;
assertEquals ( 0 , getPhase ( startedBeans . get ( 2 ) ) ) ;
assertEquals ( 99 , getPhase ( startedBeans . get ( 3 ) ) ) ;
context . stop ( ) ;
}
@Test
public void dependentShutdownFirstAndIsSmartLifecycle ( ) throws Exception {
CopyOnWriteArrayList < Lifecycle > stoppedBeans = new CopyOnWriteArrayList < Lifecycle > ( ) ;
TestSmartLifecycleBean beanMin = TestSmartLifecycleBean . forShutdownTests ( Integer . MIN_VALUE , 400 , stoppedBeans ) ;
TestSmartLifecycleBean beanNegative = TestSmartLifecycleBean . forShutdownTests ( - 99 , 100 , stoppedBeans ) ;
TestSmartLifecycleBean bean1 = TestSmartLifecycleBean . forShutdownTests ( 1 , 200 , stoppedBeans ) ;
TestSmartLifecycleBean bean2 = TestSmartLifecycleBean . forShutdownTests ( 2 , 300 , stoppedBeans ) ;
TestSmartLifecycleBean bean7 = TestSmartLifecycleBean . forShutdownTests ( 7 , 400 , stoppedBeans ) ;
TestLifecycleBean simpleBean = TestLifecycleBean . forShutdownTests ( stoppedBeans ) ;
StaticApplicationContext context = new StaticApplicationContext ( ) ;
context . getBeanFactory ( ) . registerSingleton ( "beanMin" , beanMin ) ;
context . getBeanFactory ( ) . registerSingleton ( "beanNegative" , beanNegative ) ;
context . getBeanFactory ( ) . registerSingleton ( "bean1" , bean1 ) ;
context . getBeanFactory ( ) . registerSingleton ( "bean2" , bean2 ) ;
context . getBeanFactory ( ) . registerSingleton ( "bean7" , bean7 ) ;
context . getBeanFactory ( ) . registerSingleton ( "simpleBean" , simpleBean ) ;
context . getBeanFactory ( ) . registerDependentBean ( "simpleBean" , "beanNegative" ) ;
context . refresh ( ) ;
assertTrue ( beanMin . isRunning ( ) ) ;
assertTrue ( beanNegative . isRunning ( ) ) ;
assertTrue ( bean1 . isRunning ( ) ) ;
assertTrue ( bean2 . isRunning ( ) ) ;
assertTrue ( bean7 . isRunning ( ) ) ;
// should start since it's a dependency of an auto-started bean
assertTrue ( simpleBean . isRunning ( ) ) ;
context . stop ( ) ;
assertFalse ( beanMin . isRunning ( ) ) ;
assertFalse ( beanNegative . isRunning ( ) ) ;
assertFalse ( bean1 . isRunning ( ) ) ;
assertFalse ( bean2 . isRunning ( ) ) ;
assertFalse ( bean7 . isRunning ( ) ) ;
assertFalse ( simpleBean . isRunning ( ) ) ;
assertEquals ( 6 , stoppedBeans . size ( ) ) ;
assertEquals ( 7 , getPhase ( stoppedBeans . get ( 0 ) ) ) ;
assertEquals ( 2 , getPhase ( stoppedBeans . get ( 1 ) ) ) ;
assertEquals ( 1 , getPhase ( stoppedBeans . get ( 2 ) ) ) ;
assertEquals ( - 99 , getPhase ( stoppedBeans . get ( 3 ) ) ) ;
assertEquals ( 0 , getPhase ( stoppedBeans . get ( 4 ) ) ) ;
assertEquals ( Integer . MIN_VALUE , getPhase ( stoppedBeans . get ( 5 ) ) ) ;
}
}
@Test
@Test
public void dependantShutdownFirstEvenIfNotSmartLifecycle ( ) throws Exception {
public void dependencyStartedFirstButNotSmartLifecycle ( ) throws Exception {
CopyOnWriteArrayList < Lifecycle > startedBeans = new CopyOnWriteArrayList < Lifecycle > ( ) ;
TestSmartLifecycleBean beanMin = TestSmartLifecycleBean . forStartupTests ( Integer . MIN_VALUE , startedBeans ) ;
TestSmartLifecycleBean bean7 = TestSmartLifecycleBean . forStartupTests ( 7 , startedBeans ) ;
TestLifecycleBean simpleBean = TestLifecycleBean . forStartupTests ( startedBeans ) ;
StaticApplicationContext context = new StaticApplicationContext ( ) ;
context . getBeanFactory ( ) . registerSingleton ( "beanMin" , beanMin ) ;
context . getBeanFactory ( ) . registerSingleton ( "bean7" , bean7 ) ;
context . getBeanFactory ( ) . registerSingleton ( "simpleBean" , simpleBean ) ;
context . getBeanFactory ( ) . registerDependentBean ( "simpleBean" , "beanMin" ) ;
context . refresh ( ) ;
assertTrue ( beanMin . isRunning ( ) ) ;
assertTrue ( bean7 . isRunning ( ) ) ;
assertTrue ( simpleBean . isRunning ( ) ) ;
assertEquals ( 3 , startedBeans . size ( ) ) ;
assertEquals ( 0 , getPhase ( startedBeans . get ( 0 ) ) ) ;
assertEquals ( Integer . MIN_VALUE , getPhase ( startedBeans . get ( 1 ) ) ) ;
assertEquals ( 7 , getPhase ( startedBeans . get ( 2 ) ) ) ;
context . stop ( ) ;
}
@Test
public void dependentShutdownFirstButNotSmartLifecycle ( ) throws Exception {
CopyOnWriteArrayList < Lifecycle > stoppedBeans = new CopyOnWriteArrayList < Lifecycle > ( ) ;
CopyOnWriteArrayList < Lifecycle > stoppedBeans = new CopyOnWriteArrayList < Lifecycle > ( ) ;
TestSmartLifecycleBean bean1 = new TestSmartLifecycleBean ( 1 , 200 , stoppedBeans ) ;
TestSmartLifecycleBean bean1 = TestSmartLifecycleBean . forShutdownTests ( 1 , 200 , stoppedBeans ) ;
TestLifecycleBean simpleBean = new TestLifecycleBean ( stoppedBeans ) ;
TestLifecycleBean simpleBean = TestLifecycleBean . forShutdownTests ( stoppedBeans ) ;
TestSmartLifecycleBean bean2 = new TestSmartLifecycleBean ( 2 , 300 , stoppedBeans ) ;
TestSmartLifecycleBean bean2 = TestSmartLifecycleBean . forShutdownTests ( 2 , 300 , stoppedBeans ) ;
TestSmartLifecycleBean bean7 = new TestSmartLifecycleBean ( 7 , 400 , stoppedBeans ) ;
TestSmartLifecycleBean bean7 = TestSmartLifecycleBean . forShutdownTests ( 7 , 400 , stoppedBeans ) ;
TestSmartLifecycleBean beanLast = new TestSmartLifecycleBean ( Integer . MAX_VALUE , 400 , stoppedBeans ) ;
TestSmartLifecycleBean beanMin = TestSmartLifecycleBean . forShutdownTests ( Integer . MIN _VALUE , 400 , stoppedBeans ) ;
StaticApplicationContext context = new StaticApplicationContext ( ) ;
StaticApplicationContext context = new StaticApplicationContext ( ) ;
context . getBeanFactory ( ) . registerSingleton ( "beanMin" , beanMin ) ;
context . getBeanFactory ( ) . registerSingleton ( "bean1" , bean1 ) ;
context . getBeanFactory ( ) . registerSingleton ( "bean1" , bean1 ) ;
context . getBeanFactory ( ) . registerSingleton ( "bean2" , bean2 ) ;
context . getBeanFactory ( ) . registerSingleton ( "bean2" , bean2 ) ;
context . getBeanFactory ( ) . registerSingleton ( "bean7" , bean7 ) ;
context . getBeanFactory ( ) . registerSingleton ( "bean7" , bean7 ) ;
context . getBeanFactory ( ) . registerSingleton ( "simpleBean" , simpleBean ) ;
context . getBeanFactory ( ) . registerSingleton ( "simpleBean" , simpleBean ) ;
context . getBeanFactory ( ) . registerSingleton ( "beanLast" , beanLast ) ;
context . getBeanFactory ( ) . registerDependentBean ( "bean2" , "simpleBean" ) ;
context . getBeanFactory ( ) . registerDependentBean ( "bean2" , "simpleBean" ) ;
context . refresh ( ) ;
context . refresh ( ) ;
assertTrue ( beanMin . isRunning ( ) ) ;
assertTrue ( bean1 . isRunning ( ) ) ;
assertTrue ( bean1 . isRunning ( ) ) ;
assertTrue ( bean2 . isRunning ( ) ) ;
assertTrue ( bean7 . isRunning ( ) ) ;
assertTrue ( bean7 . isRunning ( ) ) ;
assertFalse ( simpleBean . isRunning ( ) ) ;
assertFalse ( simpleBean . isRunning ( ) ) ;
simpleBean . start ( ) ;
simpleBean . start ( ) ;
assertTrue ( simpleBean . isRunning ( ) ) ;
assertTrue ( simpleBean . isRunning ( ) ) ;
context . stop ( ) ;
context . stop ( ) ;
assertFalse ( beanMin . isRunning ( ) ) ;
assertFalse ( bean1 . isRunning ( ) ) ;
assertFalse ( bean1 . isRunning ( ) ) ;
assertFalse ( bean2 . isRunning ( ) ) ;
assertFalse ( bean7 . isRunning ( ) ) ;
assertFalse ( bean7 . isRunning ( ) ) ;
assertFalse ( simpleBean . isRunning ( ) ) ;
assertFalse ( simpleBean . isRunning ( ) ) ;
assertEquals ( 5 , stoppedBeans . size ( ) ) ;
assertEquals ( 5 , stoppedBeans . size ( ) ) ;
assertEquals ( 1 , getShutdownOrder ( stoppedBeans . get ( 0 ) ) ) ;
assertEquals ( 7 , getPhase ( stoppedBeans . get ( 0 ) ) ) ;
assertEquals ( Integer . MAX_VALUE , getShutdownOrder ( stoppedBeans . get ( 1 ) ) ) ;
assertEquals ( 0 , getPhase ( stoppedBeans . get ( 1 ) ) ) ;
assertEquals ( 2 , getShutdownOrder ( stoppedBeans . get ( 2 ) ) ) ;
assertEquals ( 2 , getPhase ( stoppedBeans . get ( 2 ) ) ) ;
assertEquals ( 7 , getShutdownOrder ( stoppedBeans . get ( 3 ) ) ) ;
assertEquals ( 1 , getPhase ( stoppedBeans . get ( 3 ) ) ) ;
assertEquals ( Integer . MAX_VALUE , getShutdownOrder ( stoppedBeans . get ( 4 ) ) ) ;
assertEquals ( Integer . MIN_VALUE , getPhase ( stoppedBeans . get ( 4 ) ) ) ;
}
}
private static int getShutdownOrder ( Lifecycle lifecycle ) {
private static int getPhase ( Lifecycle lifecycle ) {
return ( lifecycle instanceof SmartLifecycle ) ?
return ( lifecycle instanceof SmartLifecycle ) ?
( ( SmartLifecycle ) lifecycle ) . getShutdownOrder ( ) : Integer . MAX_VALUE ;
( ( SmartLifecycle ) lifecycle ) . getPhase ( ) : 0 ;
}
}
private class TestLifecycleBean implements Lifecycle {
private static class TestLifecycleBean implements Lifecycle {
protected final CopyOnWriteArrayList < Lifecycle > stoppedBeans ;
private final CopyOnWriteArrayList < Lifecycle > startedBeans ;
private final CopyOnWriteArrayList < Lifecycle > stoppedBeans ;
private volatile boolean running ;
private volatile boolean running ;
TestLifecycleBean ( CopyOnWriteArrayList < Lifecycle > stoppedBeans ) {
static TestLifecycleBean forStartupTests ( CopyOnWriteArrayList < Lifecycle > startedBeans ) {
return new TestLifecycleBean ( startedBeans , null ) ;
}
static TestLifecycleBean forShutdownTests ( CopyOnWriteArrayList < Lifecycle > stoppedBeans ) {
return new TestLifecycleBean ( null , stoppedBeans ) ;
}
private TestLifecycleBean ( CopyOnWriteArrayList < Lifecycle > startedBeans , CopyOnWriteArrayList < Lifecycle > stoppedBeans ) {
this . startedBeans = startedBeans ;
this . stoppedBeans = stoppedBeans ;
this . stoppedBeans = stoppedBeans ;
}
}
@ -217,45 +515,65 @@ public class DefaultLifecycleProcessorTests {
}
}
public void start ( ) {
public void start ( ) {
if ( this . startedBeans ! = null ) {
this . startedBeans . add ( this ) ;
}
this . running = true ;
this . running = true ;
}
}
public void stop ( ) {
public void stop ( ) {
this . stoppedBeans . add ( this ) ;
if ( this . stoppedBeans ! = null ) {
this . stoppedBeans . add ( this ) ;
}
this . running = false ;
this . running = false ;
}
}
}
}
private class TestSmartLifecycleBean extends TestLifecycleBean implements SmartLifecycle {
private static class TestSmartLifecycleBean extends TestLifecycleBean implements SmartLifecycle {
private final int shutdownOrder ;
private final int phase ;
private final int shutdownDelay ;
private final int shutdownDelay ;
private volatile boolean autoStartup = true ;
static TestSmartLifecycleBean forStartupTests ( int phase , CopyOnWriteArrayList < Lifecycle > startedBeans ) {
return new TestSmartLifecycleBean ( phase , 0 , startedBeans , null ) ;
}
TestSmartLifecycleBean ( int shutdownOrder , int shutdownDelay , CopyOnWriteArrayList < Lifecycle > stoppedBeans ) {
static TestSmartLifecycleBean forShutdownTests ( int phase , int shutdownDelay , CopyOnWriteArrayList < Lifecycle > stoppedBeans ) {
super ( stoppedBeans ) ;
return new TestSmartLifecycleBean ( phase , shutdownDelay , null , stoppedBeans ) ;
this . shutdownOrder = shutdownOrder ;
}
private TestSmartLifecycleBean ( int phase , int shutdownDelay , CopyOnWriteArrayList < Lifecycle > startedBeans , CopyOnWriteArrayList < Lifecycle > stoppedBeans ) {
super ( startedBeans , stoppedBeans ) ;
this . phase = phase ;
this . shutdownDelay = shutdownDelay ;
this . shutdownDelay = shutdownDelay ;
}
}
public int getShutdownOrder ( ) {
public int getPhase ( ) {
return this . shutdownOrder ;
return this . phase ;
}
}
public boolean isAutoStartup ( ) {
public boolean isAutoStartup ( ) {
return true ;
return this . autoStartup ;
}
public void setAutoStartup ( boolean autoStartup ) {
this . autoStartup = autoStartup ;
}
}
public void stop ( final Runnable callback ) {
public void stop ( final Runnable callback ) {
// calling stop() before the delay to preserve
// invocation order in the 'stoppedBeans' list
stop ( ) ;
final int delay = this . shutdownDelay ;
final int delay = this . shutdownDelay ;
new Thread ( new Runnable ( ) {
new Thread ( new Runnable ( ) {
public void run ( ) {
public void run ( ) {
try {
try {
Thread . sleep ( delay ) ;
Thread . sleep ( delay ) ;
stop ( ) ;
}
}
catch ( InterruptedException e ) {
catch ( InterruptedException e ) {
// ignore
// ignore