diff --git a/spring-context/src/main/java/org/springframework/context/SmartLifecycle.java b/spring-context/src/main/java/org/springframework/context/SmartLifecycle.java index 5ad500d1b2..7567e0f498 100644 --- a/spring-context/src/main/java/org/springframework/context/SmartLifecycle.java +++ b/spring-context/src/main/java/org/springframework/context/SmartLifecycle.java @@ -72,9 +72,12 @@ public interface SmartLifecycle extends Lifecycle, Phased { * {@link Lifecycle} implementations, putting the typically auto-started * {@code SmartLifecycle} beans into a later startup phase and an earlier * shutdown phase. + *
Note that certain {@code SmartLifecycle} components come with a different + * default phase: e.g. executors/schedulers with {@code Integer.MAX_VALUE / 2}. * @since 5.1 * @see #getPhase() - * @see org.springframework.context.support.DefaultLifecycleProcessor#getPhase(Lifecycle) + * @see org.springframework.scheduling.concurrent.ExecutorConfigurationSupport#DEFAULT_PHASE + * @see org.springframework.context.support.DefaultLifecycleProcessor#setTimeoutPerShutdownPhase */ int DEFAULT_PHASE = Integer.MAX_VALUE; diff --git a/spring-context/src/main/java/org/springframework/context/support/DefaultLifecycleProcessor.java b/spring-context/src/main/java/org/springframework/context/support/DefaultLifecycleProcessor.java index 91b486de53..43e4c52926 100644 --- a/spring-context/src/main/java/org/springframework/context/support/DefaultLifecycleProcessor.java +++ b/spring-context/src/main/java/org/springframework/context/support/DefaultLifecycleProcessor.java @@ -106,7 +106,7 @@ public class DefaultLifecycleProcessor implements LifecycleProcessor, BeanFactor private final Log logger = LogFactory.getLog(getClass()); - private volatile long timeoutPerShutdownPhase = 30000; + private volatile long timeoutPerShutdownPhase = 10000; private volatile boolean running; @@ -135,7 +135,7 @@ public class DefaultLifecycleProcessor implements LifecycleProcessor, BeanFactor /** * Specify the maximum time allotted in milliseconds for the shutdown of any * phase (group of {@link SmartLifecycle} beans with the same 'phase' value). - *
The default value is 30000 milliseconds (30 seconds). + *
The default value is 10000 milliseconds (10 seconds) as of 6.2.
* @see SmartLifecycle#getPhase()
*/
public void setTimeoutPerShutdownPhase(long timeoutPerShutdownPhase) {
diff --git a/spring-context/src/main/java/org/springframework/scheduling/concurrent/ExecutorConfigurationSupport.java b/spring-context/src/main/java/org/springframework/scheduling/concurrent/ExecutorConfigurationSupport.java
index 5f20eb75af..2bb0c6666f 100644
--- a/spring-context/src/main/java/org/springframework/scheduling/concurrent/ExecutorConfigurationSupport.java
+++ b/spring-context/src/main/java/org/springframework/scheduling/concurrent/ExecutorConfigurationSupport.java
@@ -33,6 +33,7 @@ import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ApplicationListener;
+import org.springframework.context.Lifecycle;
import org.springframework.context.SmartLifecycle;
import org.springframework.context.event.ContextClosedEvent;
import org.springframework.lang.Nullable;
@@ -58,6 +59,20 @@ public abstract class ExecutorConfigurationSupport extends CustomizableThreadFac
implements BeanNameAware, ApplicationContextAware, InitializingBean, DisposableBean,
SmartLifecycle, ApplicationListener This is different from the default phase {@code Integer.MAX_VALUE} associated with
+ * other {@link SmartLifecycle} implementations, putting the typically auto-started
+ * executor/scheduler beans into an earlier startup phase and a later shutdown phase while
+ * still leaving room for regular {@link Lifecycle} components with the common phase 0.
+ * @since 6.2
+ * @see #getPhase()
+ * @see SmartLifecycle#DEFAULT_PHASE
+ * @see org.springframework.context.support.DefaultLifecycleProcessor#setTimeoutPerShutdownPhase
+ */
+ public static final int DEFAULT_PHASE = Integer.MAX_VALUE / 2;
+
+
protected final Log logger = LogFactory.getLog(getClass());
private ThreadFactory threadFactory = this;
@@ -218,7 +233,8 @@ public abstract class ExecutorConfigurationSupport extends CustomizableThreadFac
/**
* Specify the lifecycle phase for pausing and resuming this executor.
- * The default is {@link #DEFAULT_PHASE}.
+ * The default for executors/schedulers is {@link #DEFAULT_PHASE} as of 6.2,
+ * for stopping after other {@link SmartLifecycle} implementations.
* @since 6.1
* @see SmartLifecycle#getPhase()
*/
diff --git a/spring-context/src/main/java/org/springframework/scheduling/concurrent/SimpleAsyncTaskScheduler.java b/spring-context/src/main/java/org/springframework/scheduling/concurrent/SimpleAsyncTaskScheduler.java
index 5be8c7df33..3b162ce973 100644
--- a/spring-context/src/main/java/org/springframework/scheduling/concurrent/SimpleAsyncTaskScheduler.java
+++ b/spring-context/src/main/java/org/springframework/scheduling/concurrent/SimpleAsyncTaskScheduler.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2023 the original author or authors.
+ * Copyright 2002-2024 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.
@@ -91,6 +91,14 @@ import org.springframework.util.ErrorHandler;
public class SimpleAsyncTaskScheduler extends SimpleAsyncTaskExecutor implements TaskScheduler,
ApplicationContextAware, SmartLifecycle, ApplicationListener