@@ -106,6 +106,8 @@ public class DefaultLifecycleProcessor implements LifecycleProcessor, BeanFactor
106
106
107
107
private final Log logger = LogFactory .getLog (getClass ());
108
108
109
+ private final Map <Integer , Long > timeoutsForShutdownPhases = new ConcurrentHashMap <>();
110
+
109
111
private volatile long timeoutPerShutdownPhase = 10000 ;
110
112
111
113
private volatile boolean running ;
@@ -132,6 +134,37 @@ else if (checkpointOnRefresh) {
132
134
}
133
135
134
136
137
+ /**
138
+ * Specify the maximum time allotted for the shutdown of each given phase
139
+ * (group of {@link SmartLifecycle} beans with the same 'phase' value).
140
+ * <p>In case of no specific timeout configured, the default timeout per
141
+ * shutdown phase will apply: 10000 milliseconds (10 seconds) as of 6.2.
142
+ * @param timeoutsForShutdownPhases a map of phase values (matching
143
+ * {@link SmartLifecycle#getPhase()}) and corresponding timeout values
144
+ * (in milliseconds)
145
+ * @since 6.2
146
+ * @see SmartLifecycle#getPhase()
147
+ * @see #setTimeoutPerShutdownPhase
148
+ */
149
+ public void setTimeoutsForShutdownPhases (Map <Integer , Long > timeoutsForShutdownPhases ) {
150
+ this .timeoutsForShutdownPhases .putAll (timeoutsForShutdownPhases );
151
+ }
152
+
153
+ /**
154
+ * Specify the maximum time allotted for the shutdown of a specific phase
155
+ * (group of {@link SmartLifecycle} beans with the same 'phase' value).
156
+ * <p>In case of no specific timeout configured, the default timeout per
157
+ * shutdown phase will apply: 10000 milliseconds (10 seconds) as of 6.2.
158
+ * @param phase the phase value (matching {@link SmartLifecycle#getPhase()})
159
+ * @param timeout the corresponding timeout value (in milliseconds)
160
+ * @since 6.2
161
+ * @see SmartLifecycle#getPhase()
162
+ * @see #setTimeoutPerShutdownPhase
163
+ */
164
+ public void setTimeoutForShutdownPhase (int phase , long timeout ) {
165
+ this .timeoutsForShutdownPhases .put (phase , timeout );
166
+ }
167
+
135
168
/**
136
169
* Specify the maximum time allotted in milliseconds for the shutdown of any
137
170
* phase (group of {@link SmartLifecycle} beans with the same 'phase' value).
@@ -142,6 +175,11 @@ public void setTimeoutPerShutdownPhase(long timeoutPerShutdownPhase) {
142
175
this .timeoutPerShutdownPhase = timeoutPerShutdownPhase ;
143
176
}
144
177
178
+ private long determineTimeout (int phase ) {
179
+ Long timeout = this .timeoutsForShutdownPhases .get (phase );
180
+ return (timeout != null ? timeout : this .timeoutPerShutdownPhase );
181
+ }
182
+
145
183
@ Override
146
184
public void setBeanFactory (BeanFactory beanFactory ) {
147
185
if (!(beanFactory instanceof ConfigurableListableBeanFactory clbf )) {
@@ -250,13 +288,13 @@ private void startBeans(boolean autoStartupOnly) {
250
288
251
289
lifecycleBeans .forEach ((beanName , bean ) -> {
252
290
if (!autoStartupOnly || isAutoStartupCandidate (beanName , bean )) {
253
- int phase = getPhase (bean );
254
- phases .computeIfAbsent (
255
- phase ,
256
- p -> new LifecycleGroup (phase , this .timeoutPerShutdownPhase , lifecycleBeans , autoStartupOnly )
291
+ int startupPhase = getPhase (bean );
292
+ phases .computeIfAbsent (startupPhase ,
293
+ phase -> new LifecycleGroup (phase , determineTimeout (phase ), lifecycleBeans , autoStartupOnly )
257
294
).add (beanName , bean );
258
295
}
259
296
});
297
+
260
298
if (!phases .isEmpty ()) {
261
299
phases .values ().forEach (LifecycleGroup ::start );
262
300
}
@@ -307,13 +345,14 @@ private boolean toBeStarted(String beanName, Lifecycle bean) {
307
345
private void stopBeans () {
308
346
Map <String , Lifecycle > lifecycleBeans = getLifecycleBeans ();
309
347
Map <Integer , LifecycleGroup > phases = new TreeMap <>(Comparator .reverseOrder ());
348
+
310
349
lifecycleBeans .forEach ((beanName , bean ) -> {
311
350
int shutdownPhase = getPhase (bean );
312
- phases .computeIfAbsent (
313
- shutdownPhase ,
314
- p -> new LifecycleGroup (shutdownPhase , this .timeoutPerShutdownPhase , lifecycleBeans , false )
351
+ phases .computeIfAbsent (shutdownPhase ,
352
+ phase -> new LifecycleGroup (phase , determineTimeout (phase ), lifecycleBeans , false )
315
353
).add (beanName , bean );
316
354
});
355
+
317
356
if (!phases .isEmpty ()) {
318
357
phases .values ().forEach (LifecycleGroup ::stop );
319
358
}
0 commit comments