1
1
/*
2
- * Copyright 2002-2009 the original author or authors.
2
+ * Copyright 2002-2010 the original author or authors.
3
3
*
4
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
5
* you may not use this file except in compliance with the License.
20
20
import java .util .Collections ;
21
21
import java .util .HashMap ;
22
22
import java .util .LinkedHashMap ;
23
+ import java .util .LinkedHashSet ;
23
24
import java .util .List ;
24
25
import java .util .Map ;
26
+ import java .util .Set ;
25
27
import java .util .concurrent .CountDownLatch ;
26
28
import java .util .concurrent .TimeUnit ;
27
29
47
49
*/
48
50
public class DefaultLifecycleProcessor implements LifecycleProcessor , BeanFactoryAware {
49
51
50
- private final Log logger = LogFactory .getLog (this . getClass ());
52
+ private final Log logger = LogFactory .getLog (getClass ());
51
53
52
54
private volatile long timeoutPerShutdownPhase = 30000 ;
53
55
@@ -156,7 +158,13 @@ private void doStart(Map<String, ? extends Lifecycle> lifecycleBeans, String bea
156
158
doStart (lifecycleBeans , dependency );
157
159
}
158
160
if (!bean .isRunning ()) {
161
+ if (logger .isDebugEnabled ()) {
162
+ logger .debug ("Starting bean '" + beanName + "' of type [" + bean .getClass () + "]" );
163
+ }
159
164
bean .start ();
165
+ if (logger .isDebugEnabled ()) {
166
+ logger .debug ("Successfully started bean '" + beanName + "'" );
167
+ }
160
168
}
161
169
lifecycleBeans .remove (beanName );
162
170
}
@@ -190,28 +198,51 @@ private void stopBeans() {
190
198
* @param lifecycleBeans Map with bean name as key and Lifecycle instance as value
191
199
* @param beanName the name of the bean to stop
192
200
*/
193
- private void doStop (Map <String , ? extends Lifecycle > lifecycleBeans , String beanName , final CountDownLatch latch ) {
201
+ private void doStop (Map <String , ? extends Lifecycle > lifecycleBeans , final String beanName ,
202
+ final CountDownLatch latch , final Set <String > countDownBeanNames ) {
203
+
194
204
Lifecycle bean = lifecycleBeans .get (beanName );
195
205
if (bean != null ) {
196
206
String [] dependentBeans = this .beanFactory .getDependentBeans (beanName );
197
207
for (String dependentBean : dependentBeans ) {
198
- doStop (lifecycleBeans , dependentBean , latch );
208
+ doStop (lifecycleBeans , dependentBean , latch , countDownBeanNames );
199
209
}
200
- if (bean .isRunning ()) {
201
- if (bean instanceof SmartLifecycle ) {
202
- ((SmartLifecycle ) bean ).stop (new Runnable () {
203
- public void run () {
204
- latch .countDown ();
210
+ try {
211
+ if (bean .isRunning ()) {
212
+ if (bean instanceof SmartLifecycle ) {
213
+ if (logger .isDebugEnabled ()) {
214
+ logger .debug ("Asking bean '" + beanName + "' of type [" + bean .getClass () + "] to stop" );
215
+ }
216
+ countDownBeanNames .add (beanName );
217
+ ((SmartLifecycle ) bean ).stop (new Runnable () {
218
+ public void run () {
219
+ latch .countDown ();
220
+ countDownBeanNames .remove (beanName );
221
+ if (logger .isDebugEnabled ()) {
222
+ logger .debug ("Bean '" + beanName + "' completed its stop procedure" );
223
+ }
224
+ }
225
+ });
226
+ }
227
+ else {
228
+ if (logger .isDebugEnabled ()) {
229
+ logger .debug ("Stopping bean '" + beanName + "' of type [" + bean .getClass () + "]" );
230
+ }
231
+ bean .stop ();
232
+ if (logger .isDebugEnabled ()) {
233
+ logger .debug ("Successfully stopped bean '" + beanName + "'" );
205
234
}
206
- });
235
+ }
207
236
}
208
- else {
209
- bean .stop ();
237
+ else if (bean instanceof SmartLifecycle ) {
238
+ // don't wait for beans that aren't running
239
+ latch .countDown ();
210
240
}
211
241
}
212
- else if (bean instanceof SmartLifecycle ) {
213
- // don't wait for beans that aren't running
214
- latch .countDown ();
242
+ catch (Throwable ex ) {
243
+ if (logger .isWarnEnabled ()) {
244
+ logger .warn ("Failed to stop bean '" + beanName + "'" , ex );
245
+ }
215
246
}
216
247
lifecycleBeans .remove (beanName );
217
248
}
@@ -288,26 +319,33 @@ public void add(String name, Lifecycle bean) {
288
319
}
289
320
290
321
public void start () {
291
- if (members .size () == 0 ) {
322
+ if (this . members .isEmpty () ) {
292
323
return ;
293
324
}
294
- Collections .sort (members );
295
- for (LifecycleGroupMember member : members ) {
296
- if (lifecycleBeans .containsKey (member .name )) {
297
- doStart (lifecycleBeans , member .name );
325
+ if (logger .isInfoEnabled ()) {
326
+ logger .info ("Starting beans in phase " + this .phase );
327
+ }
328
+ Collections .sort (this .members );
329
+ for (LifecycleGroupMember member : this .members ) {
330
+ if (this .lifecycleBeans .containsKey (member .name )) {
331
+ doStart (this .lifecycleBeans , member .name );
298
332
}
299
333
}
300
334
}
301
335
302
336
public void stop () {
303
- if (members .size () == 0 ) {
337
+ if (this . members .isEmpty () ) {
304
338
return ;
305
339
}
306
- Collections .sort (members , Collections .reverseOrder ());
307
- final CountDownLatch latch = new CountDownLatch (this .smartMemberCount );
308
- for (LifecycleGroupMember member : members ) {
309
- if (lifecycleBeans .containsKey (member .name )) {
310
- doStop (lifecycleBeans , member .name , latch );
340
+ if (logger .isInfoEnabled ()) {
341
+ logger .info ("Stopping beans in phase " + this .phase );
342
+ }
343
+ Collections .sort (this .members , Collections .reverseOrder ());
344
+ CountDownLatch latch = new CountDownLatch (this .smartMemberCount );
345
+ Set <String > countDownBeanNames = Collections .synchronizedSet (new LinkedHashSet <String >());
346
+ for (LifecycleGroupMember member : this .members ) {
347
+ if (this .lifecycleBeans .containsKey (member .name )) {
348
+ doStop (this .lifecycleBeans , member .name , latch , countDownBeanNames );
311
349
}
312
350
else if (member .bean instanceof SmartLifecycle ) {
313
351
// already removed, must have been a dependent
@@ -316,14 +354,13 @@ else if (member.bean instanceof SmartLifecycle) {
316
354
}
317
355
try {
318
356
latch .await (this .timeout , TimeUnit .MILLISECONDS );
319
- if (latch .getCount () != 0 ) {
320
- if (logger .isWarnEnabled ()) {
321
- logger .warn ("failed to shutdown beans with phase value " +
322
- this .phase + " within timeout of " + this .timeout );
323
- }
357
+ if (latch .getCount () > 0 && !countDownBeanNames .isEmpty () && logger .isWarnEnabled ()) {
358
+ logger .warn ("Failed to shut down " + countDownBeanNames .size () + " bean" +
359
+ (countDownBeanNames .size () > 1 ? "s" : "" ) + " with phase value " +
360
+ this .phase + " within timeout of " + this .timeout + ": " + countDownBeanNames );
324
361
}
325
362
}
326
- catch (InterruptedException e ) {
363
+ catch (InterruptedException ex ) {
327
364
Thread .currentThread ().interrupt ();
328
365
}
329
366
}
0 commit comments