1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.springframework.context.support;
18
19 import java.util.concurrent.CopyOnWriteArrayList;
20
21 import org.junit.Test;
22
23 import org.springframework.beans.DirectFieldAccessor;
24 import org.springframework.beans.factory.FactoryBean;
25 import org.springframework.beans.factory.config.BeanDefinition;
26 import org.springframework.beans.factory.support.RootBeanDefinition;
27 import org.springframework.context.Lifecycle;
28 import org.springframework.context.LifecycleProcessor;
29 import org.springframework.context.SmartLifecycle;
30 import org.springframework.tests.Assume;
31 import org.springframework.tests.TestGroup;
32
33 import static org.junit.Assert.*;
34
35
36
37
38
39 public class DefaultLifecycleProcessorTests {
40
41 @Test
42 public void defaultLifecycleProcessorInstance() {
43 StaticApplicationContext context = new StaticApplicationContext();
44 context.refresh();
45 Object lifecycleProcessor = new DirectFieldAccessor(context).getPropertyValue("lifecycleProcessor");
46 assertNotNull(lifecycleProcessor);
47 assertEquals(DefaultLifecycleProcessor.class, lifecycleProcessor.getClass());
48 }
49
50 @Test
51 public void customLifecycleProcessorInstance() {
52 BeanDefinition beanDefinition = new RootBeanDefinition(DefaultLifecycleProcessor.class);
53 beanDefinition.getPropertyValues().addPropertyValue("timeoutPerShutdownPhase", 1000);
54 StaticApplicationContext context = new StaticApplicationContext();
55 context.registerBeanDefinition("lifecycleProcessor", beanDefinition);
56 context.refresh();
57 LifecycleProcessor bean = context.getBean("lifecycleProcessor", LifecycleProcessor.class);
58 Object contextLifecycleProcessor = new DirectFieldAccessor(context).getPropertyValue("lifecycleProcessor");
59 assertNotNull(contextLifecycleProcessor);
60 assertSame(bean, contextLifecycleProcessor);
61 assertEquals(1000L, new DirectFieldAccessor(contextLifecycleProcessor).getPropertyValue(
62 "timeoutPerShutdownPhase"));
63 }
64
65 @Test
66 public void singleSmartLifecycleAutoStartup() throws Exception {
67 CopyOnWriteArrayList<Lifecycle> startedBeans = new CopyOnWriteArrayList<Lifecycle>();
68 TestSmartLifecycleBean bean = TestSmartLifecycleBean.forStartupTests(1, startedBeans);
69 bean.setAutoStartup(true);
70 StaticApplicationContext context = new StaticApplicationContext();
71 context.getBeanFactory().registerSingleton("bean", bean);
72 assertFalse(bean.isRunning());
73 context.refresh();
74 assertTrue(bean.isRunning());
75 context.stop();
76 assertFalse(bean.isRunning());
77 assertEquals(1, startedBeans.size());
78 }
79
80 @Test
81 public void singleSmartLifecycleAutoStartupWithLazyInit() throws Exception {
82 StaticApplicationContext context = new StaticApplicationContext();
83 RootBeanDefinition bd = new RootBeanDefinition(DummySmartLifecycleBean.class);
84 bd.setLazyInit(true);
85 context.registerBeanDefinition("bean", bd);
86 context.refresh();
87 DummySmartLifecycleBean bean = context.getBean("bean", DummySmartLifecycleBean.class);
88 assertTrue(bean.isRunning());
89 context.stop();
90 assertFalse(bean.isRunning());
91 }
92
93 @Test
94 public void singleSmartLifecycleAutoStartupWithLazyInitFactoryBean() throws Exception {
95 StaticApplicationContext context = new StaticApplicationContext();
96 RootBeanDefinition bd = new RootBeanDefinition(DummySmartLifecycleFactoryBean.class);
97 bd.setLazyInit(true);
98 context.registerBeanDefinition("bean", bd);
99 context.refresh();
100 DummySmartLifecycleFactoryBean bean = context.getBean("&bean", DummySmartLifecycleFactoryBean.class);
101 assertTrue(bean.isRunning());
102 context.stop();
103 assertFalse(bean.isRunning());
104 }
105
106 @Test
107 public void singleSmartLifecycleWithoutAutoStartup() throws Exception {
108 CopyOnWriteArrayList<Lifecycle> startedBeans = new CopyOnWriteArrayList<Lifecycle>();
109 TestSmartLifecycleBean bean = TestSmartLifecycleBean.forStartupTests(1, startedBeans);
110 bean.setAutoStartup(false);
111 StaticApplicationContext context = new StaticApplicationContext();
112 context.getBeanFactory().registerSingleton("bean", bean);
113 assertFalse(bean.isRunning());
114 context.refresh();
115 assertFalse(bean.isRunning());
116 assertEquals(0, startedBeans.size());
117 context.start();
118 assertTrue(bean.isRunning());
119 assertEquals(1, startedBeans.size());
120 context.stop();
121 }
122
123 @Test
124 public void singleSmartLifecycleAutoStartupWithNonAutoStartupDependency() throws Exception {
125 CopyOnWriteArrayList<Lifecycle> startedBeans = new CopyOnWriteArrayList<Lifecycle>();
126 TestSmartLifecycleBean bean = TestSmartLifecycleBean.forStartupTests(1, startedBeans);
127 bean.setAutoStartup(true);
128 TestSmartLifecycleBean dependency = TestSmartLifecycleBean.forStartupTests(1, startedBeans);
129 dependency.setAutoStartup(false);
130 StaticApplicationContext context = new StaticApplicationContext();
131 context.getBeanFactory().registerSingleton("bean", bean);
132 context.getBeanFactory().registerSingleton("dependency", dependency);
133 context.getBeanFactory().registerDependentBean("dependency", "bean");
134 assertFalse(bean.isRunning());
135 assertFalse(dependency.isRunning());
136 context.refresh();
137 assertTrue(bean.isRunning());
138 assertFalse(dependency.isRunning());
139 context.stop();
140 assertFalse(bean.isRunning());
141 assertFalse(dependency.isRunning());
142 assertEquals(1, startedBeans.size());
143 }
144
145 @Test
146 public void smartLifecycleGroupStartup() throws Exception {
147 CopyOnWriteArrayList<Lifecycle> startedBeans = new CopyOnWriteArrayList<Lifecycle>();
148 TestSmartLifecycleBean beanMin = TestSmartLifecycleBean.forStartupTests(Integer.MIN_VALUE, startedBeans);
149 TestSmartLifecycleBean bean1 = TestSmartLifecycleBean.forStartupTests(1, startedBeans);
150 TestSmartLifecycleBean bean2 = TestSmartLifecycleBean.forStartupTests(2, startedBeans);
151 TestSmartLifecycleBean bean3 = TestSmartLifecycleBean.forStartupTests(3, startedBeans);
152 TestSmartLifecycleBean beanMax = TestSmartLifecycleBean.forStartupTests(Integer.MAX_VALUE, startedBeans);
153 StaticApplicationContext context = new StaticApplicationContext();
154 context.getBeanFactory().registerSingleton("bean3", bean3);
155 context.getBeanFactory().registerSingleton("beanMin", beanMin);
156 context.getBeanFactory().registerSingleton("bean2", bean2);
157 context.getBeanFactory().registerSingleton("beanMax", beanMax);
158 context.getBeanFactory().registerSingleton("bean1", bean1);
159 assertFalse(beanMin.isRunning());
160 assertFalse(bean1.isRunning());
161 assertFalse(bean2.isRunning());
162 assertFalse(bean3.isRunning());
163 assertFalse(beanMax.isRunning());
164 context.refresh();
165 assertTrue(beanMin.isRunning());
166 assertTrue(bean1.isRunning());
167 assertTrue(bean2.isRunning());
168 assertTrue(bean3.isRunning());
169 assertTrue(beanMax.isRunning());
170 context.stop();
171 assertEquals(5, startedBeans.size());
172 assertEquals(Integer.MIN_VALUE, getPhase(startedBeans.get(0)));
173 assertEquals(1, getPhase(startedBeans.get(1)));
174 assertEquals(2, getPhase(startedBeans.get(2)));
175 assertEquals(3, getPhase(startedBeans.get(3)));
176 assertEquals(Integer.MAX_VALUE, getPhase(startedBeans.get(4)));
177 }
178
179 @Test
180 public void contextRefreshThenStartWithMixedBeans() throws Exception {
181 CopyOnWriteArrayList<Lifecycle> startedBeans = new CopyOnWriteArrayList<Lifecycle>();
182 TestLifecycleBean simpleBean1 = TestLifecycleBean.forStartupTests(startedBeans);
183 TestLifecycleBean simpleBean2 = TestLifecycleBean.forStartupTests(startedBeans);
184 TestSmartLifecycleBean smartBean1 = TestSmartLifecycleBean.forStartupTests(5, startedBeans);
185 TestSmartLifecycleBean smartBean2 = TestSmartLifecycleBean.forStartupTests(-3, startedBeans);
186 StaticApplicationContext context = new StaticApplicationContext();
187 context.getBeanFactory().registerSingleton("simpleBean1", simpleBean1);
188 context.getBeanFactory().registerSingleton("smartBean1", smartBean1);
189 context.getBeanFactory().registerSingleton("simpleBean2", simpleBean2);
190 context.getBeanFactory().registerSingleton("smartBean2", smartBean2);
191 assertFalse(simpleBean1.isRunning());
192 assertFalse(simpleBean2.isRunning());
193 assertFalse(smartBean1.isRunning());
194 assertFalse(smartBean2.isRunning());
195 context.refresh();
196 assertTrue(smartBean1.isRunning());
197 assertTrue(smartBean2.isRunning());
198 assertFalse(simpleBean1.isRunning());
199 assertFalse(simpleBean2.isRunning());
200 assertEquals(2, startedBeans.size());
201 assertEquals(-3, getPhase(startedBeans.get(0)));
202 assertEquals(5, getPhase(startedBeans.get(1)));
203 context.start();
204 assertTrue(smartBean1.isRunning());
205 assertTrue(smartBean2.isRunning());
206 assertTrue(simpleBean1.isRunning());
207 assertTrue(simpleBean2.isRunning());
208 assertEquals(4, startedBeans.size());
209 assertEquals(0, getPhase(startedBeans.get(2)));
210 assertEquals(0, getPhase(startedBeans.get(3)));
211 }
212
213 @Test
214 public void contextRefreshThenStopAndRestartWithMixedBeans() throws Exception {
215 CopyOnWriteArrayList<Lifecycle> startedBeans = new CopyOnWriteArrayList<Lifecycle>();
216 TestLifecycleBean simpleBean1 = TestLifecycleBean.forStartupTests(startedBeans);
217 TestLifecycleBean simpleBean2 = TestLifecycleBean.forStartupTests(startedBeans);
218 TestSmartLifecycleBean smartBean1 = TestSmartLifecycleBean.forStartupTests(5, startedBeans);
219 TestSmartLifecycleBean smartBean2 = TestSmartLifecycleBean.forStartupTests(-3, startedBeans);
220 StaticApplicationContext context = new StaticApplicationContext();
221 context.getBeanFactory().registerSingleton("simpleBean1", simpleBean1);
222 context.getBeanFactory().registerSingleton("smartBean1", smartBean1);
223 context.getBeanFactory().registerSingleton("simpleBean2", simpleBean2);
224 context.getBeanFactory().registerSingleton("smartBean2", smartBean2);
225 assertFalse(simpleBean1.isRunning());
226 assertFalse(simpleBean2.isRunning());
227 assertFalse(smartBean1.isRunning());
228 assertFalse(smartBean2.isRunning());
229 context.refresh();
230 assertTrue(smartBean1.isRunning());
231 assertTrue(smartBean2.isRunning());
232 assertFalse(simpleBean1.isRunning());
233 assertFalse(simpleBean2.isRunning());
234 assertEquals(2, startedBeans.size());
235 assertEquals(-3, getPhase(startedBeans.get(0)));
236 assertEquals(5, getPhase(startedBeans.get(1)));
237 context.stop();
238 assertFalse(simpleBean1.isRunning());
239 assertFalse(simpleBean2.isRunning());
240 assertFalse(smartBean1.isRunning());
241 assertFalse(smartBean2.isRunning());
242 context.start();
243 assertTrue(smartBean1.isRunning());
244 assertTrue(smartBean2.isRunning());
245 assertTrue(simpleBean1.isRunning());
246 assertTrue(simpleBean2.isRunning());
247 assertEquals(6, startedBeans.size());
248 assertEquals(-3, getPhase(startedBeans.get(2)));
249 assertEquals(0, getPhase(startedBeans.get(3)));
250 assertEquals(0, getPhase(startedBeans.get(4)));
251 assertEquals(5, getPhase(startedBeans.get(5)));
252 }
253
254 @Test
255 public void smartLifecycleGroupShutdown() throws Exception {
256 Assume.group(TestGroup.PERFORMANCE);
257
258 CopyOnWriteArrayList<Lifecycle> stoppedBeans = new CopyOnWriteArrayList<Lifecycle>();
259 TestSmartLifecycleBean bean1 = TestSmartLifecycleBean.forShutdownTests(1, 300, stoppedBeans);
260 TestSmartLifecycleBean bean2 = TestSmartLifecycleBean.forShutdownTests(3, 100, stoppedBeans);
261 TestSmartLifecycleBean bean3 = TestSmartLifecycleBean.forShutdownTests(1, 600, stoppedBeans);
262 TestSmartLifecycleBean bean4 = TestSmartLifecycleBean.forShutdownTests(2, 400, stoppedBeans);
263 TestSmartLifecycleBean bean5 = TestSmartLifecycleBean.forShutdownTests(2, 700, stoppedBeans);
264 TestSmartLifecycleBean bean6 = TestSmartLifecycleBean.forShutdownTests(Integer.MAX_VALUE, 200, stoppedBeans);
265 TestSmartLifecycleBean bean7 = TestSmartLifecycleBean.forShutdownTests(3, 200, stoppedBeans);
266 StaticApplicationContext context = new StaticApplicationContext();
267 context.getBeanFactory().registerSingleton("bean1", bean1);
268 context.getBeanFactory().registerSingleton("bean2", bean2);
269 context.getBeanFactory().registerSingleton("bean3", bean3);
270 context.getBeanFactory().registerSingleton("bean4", bean4);
271 context.getBeanFactory().registerSingleton("bean5", bean5);
272 context.getBeanFactory().registerSingleton("bean6", bean6);
273 context.getBeanFactory().registerSingleton("bean7", bean7);
274 context.refresh();
275 context.stop();
276 assertEquals(Integer.MAX_VALUE, getPhase(stoppedBeans.get(0)));
277 assertEquals(3, getPhase(stoppedBeans.get(1)));
278 assertEquals(3, getPhase(stoppedBeans.get(2)));
279 assertEquals(2, getPhase(stoppedBeans.get(3)));
280 assertEquals(2, getPhase(stoppedBeans.get(4)));
281 assertEquals(1, getPhase(stoppedBeans.get(5)));
282 assertEquals(1, getPhase(stoppedBeans.get(6)));
283 }
284
285 @Test
286 public void singleSmartLifecycleShutdown() throws Exception {
287 Assume.group(TestGroup.PERFORMANCE);
288
289 CopyOnWriteArrayList<Lifecycle> stoppedBeans = new CopyOnWriteArrayList<Lifecycle>();
290 TestSmartLifecycleBean bean = TestSmartLifecycleBean.forShutdownTests(99, 300, stoppedBeans);
291 StaticApplicationContext context = new StaticApplicationContext();
292 context.getBeanFactory().registerSingleton("bean", bean);
293 context.refresh();
294 assertTrue(bean.isRunning());
295 context.stop();
296 assertEquals(1, stoppedBeans.size());
297 assertFalse(bean.isRunning());
298 assertEquals(bean, stoppedBeans.get(0));
299 }
300
301 @Test
302 public void singleLifecycleShutdown() throws Exception {
303 CopyOnWriteArrayList<Lifecycle> stoppedBeans = new CopyOnWriteArrayList<Lifecycle>();
304 Lifecycle bean = new TestLifecycleBean(null, stoppedBeans);
305 StaticApplicationContext context = new StaticApplicationContext();
306 context.getBeanFactory().registerSingleton("bean", bean);
307 context.refresh();
308 assertFalse(bean.isRunning());
309 bean.start();
310 assertTrue(bean.isRunning());
311 context.stop();
312 assertEquals(1, stoppedBeans.size());
313 assertFalse(bean.isRunning());
314 assertEquals(bean, stoppedBeans.get(0));
315 }
316
317 @Test
318 public void mixedShutdown() throws Exception {
319 CopyOnWriteArrayList<Lifecycle> stoppedBeans = new CopyOnWriteArrayList<Lifecycle>();
320 Lifecycle bean1 = TestLifecycleBean.forShutdownTests(stoppedBeans);
321 Lifecycle bean2 = TestSmartLifecycleBean.forShutdownTests(500, 200, stoppedBeans);
322 Lifecycle bean3 = TestSmartLifecycleBean.forShutdownTests(Integer.MAX_VALUE, 100, stoppedBeans);
323 Lifecycle bean4 = TestLifecycleBean.forShutdownTests(stoppedBeans);
324 Lifecycle bean5 = TestSmartLifecycleBean.forShutdownTests(1, 200, stoppedBeans);
325 Lifecycle bean6 = TestSmartLifecycleBean.forShutdownTests(-1, 100, stoppedBeans);
326 Lifecycle bean7 = TestSmartLifecycleBean.forShutdownTests(Integer.MIN_VALUE, 300, stoppedBeans);
327 StaticApplicationContext context = new StaticApplicationContext();
328 context.getBeanFactory().registerSingleton("bean1", bean1);
329 context.getBeanFactory().registerSingleton("bean2", bean2);
330 context.getBeanFactory().registerSingleton("bean3", bean3);
331 context.getBeanFactory().registerSingleton("bean4", bean4);
332 context.getBeanFactory().registerSingleton("bean5", bean5);
333 context.getBeanFactory().registerSingleton("bean6", bean6);
334 context.getBeanFactory().registerSingleton("bean7", bean7);
335 context.refresh();
336 assertTrue(bean2.isRunning());
337 assertTrue(bean3.isRunning());
338 assertTrue(bean5.isRunning());
339 assertTrue(bean6.isRunning());
340 assertTrue(bean7.isRunning());
341 assertFalse(bean1.isRunning());
342 assertFalse(bean4.isRunning());
343 bean1.start();
344 bean4.start();
345 assertTrue(bean1.isRunning());
346 assertTrue(bean4.isRunning());
347 context.stop();
348 assertFalse(bean1.isRunning());
349 assertFalse(bean2.isRunning());
350 assertFalse(bean3.isRunning());
351 assertFalse(bean4.isRunning());
352 assertFalse(bean5.isRunning());
353 assertFalse(bean6.isRunning());
354 assertFalse(bean7.isRunning());
355 assertEquals(7, stoppedBeans.size());
356 assertEquals(Integer.MAX_VALUE, getPhase(stoppedBeans.get(0)));
357 assertEquals(500, getPhase(stoppedBeans.get(1)));
358 assertEquals(1, getPhase(stoppedBeans.get(2)));
359 assertEquals(0, getPhase(stoppedBeans.get(3)));
360 assertEquals(0, getPhase(stoppedBeans.get(4)));
361 assertEquals(-1, getPhase(stoppedBeans.get(5)));
362 assertEquals(Integer.MIN_VALUE, getPhase(stoppedBeans.get(6)));
363 }
364
365 @Test
366 public void dependencyStartedFirstEvenIfItsPhaseIsHigher() throws Exception {
367 CopyOnWriteArrayList<Lifecycle> startedBeans = new CopyOnWriteArrayList<Lifecycle>();
368 TestSmartLifecycleBean beanMin = TestSmartLifecycleBean.forStartupTests(Integer.MIN_VALUE, startedBeans);
369 TestSmartLifecycleBean bean2 = TestSmartLifecycleBean.forStartupTests(2, startedBeans);
370 TestSmartLifecycleBean bean99 = TestSmartLifecycleBean.forStartupTests(99, startedBeans);
371 TestSmartLifecycleBean beanMax = TestSmartLifecycleBean.forStartupTests(Integer.MAX_VALUE, startedBeans);
372 StaticApplicationContext context = new StaticApplicationContext();
373 context.getBeanFactory().registerSingleton("beanMin", beanMin);
374 context.getBeanFactory().registerSingleton("bean2", bean2);
375 context.getBeanFactory().registerSingleton("bean99", bean99);
376 context.getBeanFactory().registerSingleton("beanMax", beanMax);
377 context.getBeanFactory().registerDependentBean("bean99", "bean2");
378 context.refresh();
379 assertTrue(beanMin.isRunning());
380 assertTrue(bean2.isRunning());
381 assertTrue(bean99.isRunning());
382 assertTrue(beanMax.isRunning());
383 assertEquals(4, startedBeans.size());
384 assertEquals(Integer.MIN_VALUE, getPhase(startedBeans.get(0)));
385 assertEquals(99, getPhase(startedBeans.get(1)));
386 assertEquals(bean99, startedBeans.get(1));
387 assertEquals(2, getPhase(startedBeans.get(2)));
388 assertEquals(bean2, startedBeans.get(2));
389 assertEquals(Integer.MAX_VALUE, getPhase(startedBeans.get(3)));
390 context.stop();
391 }
392
393 @Test
394 public void dependentShutdownFirstEvenIfItsPhaseIsLower() throws Exception {
395 Assume.group(TestGroup.PERFORMANCE);
396
397 CopyOnWriteArrayList<Lifecycle> stoppedBeans = new CopyOnWriteArrayList<Lifecycle>();
398 TestSmartLifecycleBean beanMin = TestSmartLifecycleBean.forShutdownTests(Integer.MIN_VALUE, 100, stoppedBeans);
399 TestSmartLifecycleBean bean1 = TestSmartLifecycleBean.forShutdownTests(1, 200, stoppedBeans);
400 TestSmartLifecycleBean bean99 = TestSmartLifecycleBean.forShutdownTests(99, 100, stoppedBeans);
401 TestSmartLifecycleBean bean2 = TestSmartLifecycleBean.forShutdownTests(2, 300, stoppedBeans);
402 TestSmartLifecycleBean bean7 = TestSmartLifecycleBean.forShutdownTests(7, 400, stoppedBeans);
403 TestSmartLifecycleBean beanMax = TestSmartLifecycleBean.forShutdownTests(Integer.MAX_VALUE, 400, stoppedBeans);
404 StaticApplicationContext context = new StaticApplicationContext();
405 context.getBeanFactory().registerSingleton("beanMin", beanMin);
406 context.getBeanFactory().registerSingleton("bean1", bean1);
407 context.getBeanFactory().registerSingleton("bean2", bean2);
408 context.getBeanFactory().registerSingleton("bean7", bean7);
409 context.getBeanFactory().registerSingleton("bean99", bean99);
410 context.getBeanFactory().registerSingleton("beanMax", beanMax);
411 context.getBeanFactory().registerDependentBean("bean99", "bean2");
412 context.refresh();
413 assertTrue(beanMin.isRunning());
414 assertTrue(bean1.isRunning());
415 assertTrue(bean2.isRunning());
416 assertTrue(bean7.isRunning());
417 assertTrue(bean99.isRunning());
418 assertTrue(beanMax.isRunning());
419 context.stop();
420 assertFalse(beanMin.isRunning());
421 assertFalse(bean1.isRunning());
422 assertFalse(bean2.isRunning());
423 assertFalse(bean7.isRunning());
424 assertFalse(bean99.isRunning());
425 assertFalse(beanMax.isRunning());
426 assertEquals(6, stoppedBeans.size());
427 assertEquals(Integer.MAX_VALUE, getPhase(stoppedBeans.get(0)));
428 assertEquals(2, getPhase(stoppedBeans.get(1)));
429 assertEquals(bean2, stoppedBeans.get(1));
430 assertEquals(99, getPhase(stoppedBeans.get(2)));
431 assertEquals(bean99, stoppedBeans.get(2));
432 assertEquals(7, getPhase(stoppedBeans.get(3)));
433 assertEquals(1, getPhase(stoppedBeans.get(4)));
434 assertEquals(Integer.MIN_VALUE, getPhase(stoppedBeans.get(5)));
435 }
436
437 @Test
438 public void dependencyStartedFirstAndIsSmartLifecycle() throws Exception {
439 CopyOnWriteArrayList<Lifecycle> startedBeans = new CopyOnWriteArrayList<Lifecycle>();
440 TestSmartLifecycleBean beanNegative = TestSmartLifecycleBean.forStartupTests(-99, startedBeans);
441 TestSmartLifecycleBean bean99 = TestSmartLifecycleBean.forStartupTests(99, startedBeans);
442 TestSmartLifecycleBean bean7 = TestSmartLifecycleBean.forStartupTests(7, startedBeans);
443 TestLifecycleBean simpleBean = TestLifecycleBean.forStartupTests(startedBeans);
444 StaticApplicationContext context = new StaticApplicationContext();
445 context.getBeanFactory().registerSingleton("beanNegative", beanNegative);
446 context.getBeanFactory().registerSingleton("bean7", bean7);
447 context.getBeanFactory().registerSingleton("bean99", bean99);
448 context.getBeanFactory().registerSingleton("simpleBean", simpleBean);
449 context.getBeanFactory().registerDependentBean("bean7", "simpleBean");
450 context.refresh();
451 context.stop();
452 startedBeans.clear();
453
454 context.start();
455 assertTrue(beanNegative.isRunning());
456 assertTrue(bean99.isRunning());
457 assertTrue(bean7.isRunning());
458 assertTrue(simpleBean.isRunning());
459 assertEquals(4, startedBeans.size());
460 assertEquals(-99, getPhase(startedBeans.get(0)));
461 assertEquals(7, getPhase(startedBeans.get(1)));
462 assertEquals(0, getPhase(startedBeans.get(2)));
463 assertEquals(99, getPhase(startedBeans.get(3)));
464 context.stop();
465 }
466
467 @Test
468 public void dependentShutdownFirstAndIsSmartLifecycle() throws Exception {
469 Assume.group(TestGroup.PERFORMANCE);
470
471 CopyOnWriteArrayList<Lifecycle> stoppedBeans = new CopyOnWriteArrayList<Lifecycle>();
472 TestSmartLifecycleBean beanMin = TestSmartLifecycleBean.forShutdownTests(Integer.MIN_VALUE, 400, stoppedBeans);
473 TestSmartLifecycleBean beanNegative = TestSmartLifecycleBean.forShutdownTests(-99, 100, stoppedBeans);
474 TestSmartLifecycleBean bean1 = TestSmartLifecycleBean.forShutdownTests(1, 200, stoppedBeans);
475 TestSmartLifecycleBean bean2 = TestSmartLifecycleBean.forShutdownTests(2, 300, stoppedBeans);
476 TestSmartLifecycleBean bean7 = TestSmartLifecycleBean.forShutdownTests(7, 400, stoppedBeans);
477 TestLifecycleBean simpleBean = TestLifecycleBean.forShutdownTests(stoppedBeans);
478 StaticApplicationContext context = new StaticApplicationContext();
479 context.getBeanFactory().registerSingleton("beanMin", beanMin);
480 context.getBeanFactory().registerSingleton("beanNegative", beanNegative);
481 context.getBeanFactory().registerSingleton("bean1", bean1);
482 context.getBeanFactory().registerSingleton("bean2", bean2);
483 context.getBeanFactory().registerSingleton("bean7", bean7);
484 context.getBeanFactory().registerSingleton("simpleBean", simpleBean);
485 context.getBeanFactory().registerDependentBean("simpleBean", "beanNegative");
486 context.refresh();
487 assertTrue(beanMin.isRunning());
488 assertTrue(beanNegative.isRunning());
489 assertTrue(bean1.isRunning());
490 assertTrue(bean2.isRunning());
491 assertTrue(bean7.isRunning());
492
493 assertTrue(simpleBean.isRunning());
494 context.stop();
495 assertFalse(beanMin.isRunning());
496 assertFalse(beanNegative.isRunning());
497 assertFalse(bean1.isRunning());
498 assertFalse(bean2.isRunning());
499 assertFalse(bean7.isRunning());
500 assertFalse(simpleBean.isRunning());
501 assertEquals(6, stoppedBeans.size());
502 assertEquals(7, getPhase(stoppedBeans.get(0)));
503 assertEquals(2, getPhase(stoppedBeans.get(1)));
504 assertEquals(1, getPhase(stoppedBeans.get(2)));
505 assertEquals(-99, getPhase(stoppedBeans.get(3)));
506 assertEquals(0, getPhase(stoppedBeans.get(4)));
507 assertEquals(Integer.MIN_VALUE, getPhase(stoppedBeans.get(5)));
508 }
509
510 @Test
511 public void dependencyStartedFirstButNotSmartLifecycle() throws Exception {
512 CopyOnWriteArrayList<Lifecycle> startedBeans = new CopyOnWriteArrayList<Lifecycle>();
513 TestSmartLifecycleBean beanMin = TestSmartLifecycleBean.forStartupTests(Integer.MIN_VALUE, startedBeans);
514 TestSmartLifecycleBean bean7 = TestSmartLifecycleBean.forStartupTests(7, startedBeans);
515 TestLifecycleBean simpleBean = TestLifecycleBean.forStartupTests(startedBeans);
516 StaticApplicationContext context = new StaticApplicationContext();
517 context.getBeanFactory().registerSingleton("beanMin", beanMin);
518 context.getBeanFactory().registerSingleton("bean7", bean7);
519 context.getBeanFactory().registerSingleton("simpleBean", simpleBean);
520 context.getBeanFactory().registerDependentBean("simpleBean", "beanMin");
521 context.refresh();
522 assertTrue(beanMin.isRunning());
523 assertTrue(bean7.isRunning());
524 assertTrue(simpleBean.isRunning());
525 assertEquals(3, startedBeans.size());
526 assertEquals(0, getPhase(startedBeans.get(0)));
527 assertEquals(Integer.MIN_VALUE, getPhase(startedBeans.get(1)));
528 assertEquals(7, getPhase(startedBeans.get(2)));
529 context.stop();
530 }
531
532 @Test
533 public void dependentShutdownFirstButNotSmartLifecycle() throws Exception {
534 Assume.group(TestGroup.PERFORMANCE);
535
536 CopyOnWriteArrayList<Lifecycle> stoppedBeans = new CopyOnWriteArrayList<Lifecycle>();
537 TestSmartLifecycleBean bean1 = TestSmartLifecycleBean.forShutdownTests(1, 200, stoppedBeans);
538 TestLifecycleBean simpleBean = TestLifecycleBean.forShutdownTests(stoppedBeans);
539 TestSmartLifecycleBean bean2 = TestSmartLifecycleBean.forShutdownTests(2, 300, stoppedBeans);
540 TestSmartLifecycleBean bean7 = TestSmartLifecycleBean.forShutdownTests(7, 400, stoppedBeans);
541 TestSmartLifecycleBean beanMin = TestSmartLifecycleBean.forShutdownTests(Integer.MIN_VALUE, 400, stoppedBeans);
542 StaticApplicationContext context = new StaticApplicationContext();
543 context.getBeanFactory().registerSingleton("beanMin", beanMin);
544 context.getBeanFactory().registerSingleton("bean1", bean1);
545 context.getBeanFactory().registerSingleton("bean2", bean2);
546 context.getBeanFactory().registerSingleton("bean7", bean7);
547 context.getBeanFactory().registerSingleton("simpleBean", simpleBean);
548 context.getBeanFactory().registerDependentBean("bean2", "simpleBean");
549 context.refresh();
550 assertTrue(beanMin.isRunning());
551 assertTrue(bean1.isRunning());
552 assertTrue(bean2.isRunning());
553 assertTrue(bean7.isRunning());
554 assertFalse(simpleBean.isRunning());
555 simpleBean.start();
556 assertTrue(simpleBean.isRunning());
557 context.stop();
558 assertFalse(beanMin.isRunning());
559 assertFalse(bean1.isRunning());
560 assertFalse(bean2.isRunning());
561 assertFalse(bean7.isRunning());
562 assertFalse(simpleBean.isRunning());
563 assertEquals(5, stoppedBeans.size());
564 assertEquals(7, getPhase(stoppedBeans.get(0)));
565 assertEquals(0, getPhase(stoppedBeans.get(1)));
566 assertEquals(2, getPhase(stoppedBeans.get(2)));
567 assertEquals(1, getPhase(stoppedBeans.get(3)));
568 assertEquals(Integer.MIN_VALUE, getPhase(stoppedBeans.get(4)));
569 }
570
571
572 private static int getPhase(Lifecycle lifecycle) {
573 return (lifecycle instanceof SmartLifecycle) ?
574 ((SmartLifecycle) lifecycle).getPhase() : 0;
575 }
576
577
578 private static class TestLifecycleBean implements Lifecycle {
579
580 private final CopyOnWriteArrayList<Lifecycle> startedBeans;
581
582 private final CopyOnWriteArrayList<Lifecycle> stoppedBeans;
583
584 private volatile boolean running;
585
586
587 static TestLifecycleBean forStartupTests(CopyOnWriteArrayList<Lifecycle> startedBeans) {
588 return new TestLifecycleBean(startedBeans, null);
589 }
590
591 static TestLifecycleBean forShutdownTests(CopyOnWriteArrayList<Lifecycle> stoppedBeans) {
592 return new TestLifecycleBean(null, stoppedBeans);
593 }
594
595 private TestLifecycleBean(CopyOnWriteArrayList<Lifecycle> startedBeans, CopyOnWriteArrayList<Lifecycle> stoppedBeans) {
596 this.startedBeans = startedBeans;
597 this.stoppedBeans = stoppedBeans;
598 }
599
600 @Override
601 public boolean isRunning() {
602 return this.running;
603 }
604
605 @Override
606 public void start() {
607 if (this.startedBeans != null) {
608 this.startedBeans.add(this);
609 }
610 this.running = true;
611 }
612
613 @Override
614 public void stop() {
615 if (this.stoppedBeans != null) {
616 this.stoppedBeans.add(this);
617 }
618 this.running = false;
619 }
620 }
621
622
623 private static class TestSmartLifecycleBean extends TestLifecycleBean implements SmartLifecycle {
624
625 private final int phase;
626
627 private final int shutdownDelay;
628
629 private volatile boolean autoStartup = true;
630
631 static TestSmartLifecycleBean forStartupTests(int phase, CopyOnWriteArrayList<Lifecycle> startedBeans) {
632 return new TestSmartLifecycleBean(phase, 0, startedBeans, null);
633 }
634
635 static TestSmartLifecycleBean forShutdownTests(int phase, int shutdownDelay, CopyOnWriteArrayList<Lifecycle> stoppedBeans) {
636 return new TestSmartLifecycleBean(phase, shutdownDelay, null, stoppedBeans);
637 }
638
639 private TestSmartLifecycleBean(int phase, int shutdownDelay, CopyOnWriteArrayList<Lifecycle> startedBeans, CopyOnWriteArrayList<Lifecycle> stoppedBeans) {
640 super(startedBeans, stoppedBeans);
641 this.phase = phase;
642 this.shutdownDelay = shutdownDelay;
643 }
644
645 @Override
646 public int getPhase() {
647 return this.phase;
648 }
649
650 @Override
651 public boolean isAutoStartup() {
652 return this.autoStartup;
653 }
654
655 public void setAutoStartup(boolean autoStartup) {
656 this.autoStartup = autoStartup;
657 }
658
659 @Override
660 public void stop(final Runnable callback) {
661
662
663 stop();
664 final int delay = this.shutdownDelay;
665 new Thread(new Runnable() {
666 @Override
667 public void run() {
668 try {
669 Thread.sleep(delay);
670 }
671 catch (InterruptedException e) {
672
673 }
674 finally {
675 callback.run();
676 }
677 }
678 }).start();
679 }
680 }
681
682
683 public static class DummySmartLifecycleBean implements SmartLifecycle {
684
685 public boolean running = false;
686
687 @Override
688 public boolean isAutoStartup() {
689 return true;
690 }
691
692 @Override
693 public void stop(Runnable callback) {
694 this.running = false;
695 callback.run();
696 }
697
698 @Override
699 public void start() {
700 this.running = true;
701 }
702
703 @Override
704 public void stop() {
705 this.running = false;
706 }
707
708 @Override
709 public boolean isRunning() {
710 return this.running;
711 }
712
713 @Override
714 public int getPhase() {
715 return 0;
716 }
717 }
718
719
720 public static class DummySmartLifecycleFactoryBean implements FactoryBean<Object>, SmartLifecycle {
721
722 public boolean running = false;
723
724 DummySmartLifecycleBean bean = new DummySmartLifecycleBean();
725
726 @Override
727 public Object getObject() throws Exception {
728 return this.bean;
729 }
730
731 @Override
732 public Class<?> getObjectType() {
733 return DummySmartLifecycleBean.class;
734 }
735
736 @Override
737 public boolean isSingleton() {
738 return true;
739 }
740
741 @Override
742 public boolean isAutoStartup() {
743 return true;
744 }
745
746 @Override
747 public void stop(Runnable callback) {
748 this.running = false;
749 callback.run();
750 }
751
752 @Override
753 public void start() {
754 this.running = true;
755 }
756
757 @Override
758 public void stop() {
759 this.running = false;
760 }
761
762 @Override
763 public boolean isRunning() {
764 return this.running;
765 }
766
767 @Override
768 public int getPhase() {
769 return 0;
770 }
771 }
772
773 }