Auto-configure a lifecycle processor with configurable timeout
Closes gh-21347
This commit is contained in:
parent
240898121f
commit
0bb687717c
|
@ -63,9 +63,9 @@ public class DocumentConfigurationProperties extends AbstractTask {
|
||||||
builder.addSection("core")
|
builder.addSection("core")
|
||||||
.withKeyPrefixes("debug", "trace", "logging", "spring.aop", "spring.application",
|
.withKeyPrefixes("debug", "trace", "logging", "spring.aop", "spring.application",
|
||||||
"spring.autoconfigure", "spring.banner", "spring.beaninfo", "spring.codec", "spring.config",
|
"spring.autoconfigure", "spring.banner", "spring.beaninfo", "spring.codec", "spring.config",
|
||||||
"spring.info", "spring.jmx", "spring.main", "spring.messages", "spring.pid", "spring.profiles",
|
"spring.info", "spring.jmx", "spring.lifecycle", "spring.main", "spring.messages", "spring.pid",
|
||||||
"spring.quartz", "spring.reactor", "spring.task", "spring.mandatory-file-encoding", "info",
|
"spring.profiles", "spring.quartz", "spring.reactor", "spring.task",
|
||||||
"spring.output.ansi.enabled")
|
"spring.mandatory-file-encoding", "info", "spring.output.ansi.enabled")
|
||||||
.addSection("mail").withKeyPrefixes("spring.mail", "spring.sendgrid").addSection("cache")
|
.addSection("mail").withKeyPrefixes("spring.mail", "spring.sendgrid").addSection("cache")
|
||||||
.withKeyPrefixes("spring.cache").addSection("server").withKeyPrefixes("server").addSection("web")
|
.withKeyPrefixes("spring.cache").addSection("server").withKeyPrefixes("server").addSection("web")
|
||||||
.withKeyPrefixes("spring.hateoas", "spring.http", "spring.servlet", "spring.jersey", "spring.mvc",
|
.withKeyPrefixes("spring.hateoas", "spring.http", "spring.servlet", "spring.jersey", "spring.mvc",
|
||||||
|
|
|
@ -0,0 +1,46 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2012-2020 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.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.springframework.boot.autoconfigure.context;
|
||||||
|
|
||||||
|
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||||
|
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.context.support.AbstractApplicationContext;
|
||||||
|
import org.springframework.context.support.DefaultLifecycleProcessor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link EnableAutoConfiguration Auto-configuration} relating to the application
|
||||||
|
* context's lifecycle.
|
||||||
|
*
|
||||||
|
* @author Andy Wilkinson
|
||||||
|
* @since 2.3.0
|
||||||
|
*/
|
||||||
|
@Configuration(proxyBeanMethods = false)
|
||||||
|
@EnableConfigurationProperties(LifecycleProperties.class)
|
||||||
|
public class LifecycleAutoConfiguration {
|
||||||
|
|
||||||
|
@Bean(name = AbstractApplicationContext.LIFECYCLE_PROCESSOR_BEAN_NAME)
|
||||||
|
@ConditionalOnMissingBean(name = AbstractApplicationContext.LIFECYCLE_PROCESSOR_BEAN_NAME)
|
||||||
|
public DefaultLifecycleProcessor defaultLifecycleProcessor(LifecycleProperties properties) {
|
||||||
|
DefaultLifecycleProcessor lifecycleProcessor = new DefaultLifecycleProcessor();
|
||||||
|
lifecycleProcessor.setTimeoutPerShutdownPhase(properties.getTimeoutPerShutdownPhase().toMillis());
|
||||||
|
return lifecycleProcessor;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,46 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2012-2020 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.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.springframework.boot.autoconfigure.context;
|
||||||
|
|
||||||
|
import java.time.Duration;
|
||||||
|
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configuration properties for lifecycle processing.
|
||||||
|
*
|
||||||
|
* @author Andy Wilkinson
|
||||||
|
* @since 2.3.0
|
||||||
|
*/
|
||||||
|
@ConfigurationProperties(prefix = "spring.lifecycle")
|
||||||
|
public class LifecycleProperties {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Timeout for the shutdown of any phase (group of SmartLifecycle beans with the same
|
||||||
|
* 'phase' value).
|
||||||
|
*/
|
||||||
|
private Duration timeoutPerShutdownPhase = Duration.ofSeconds(30);
|
||||||
|
|
||||||
|
public Duration getTimeoutPerShutdownPhase() {
|
||||||
|
return this.timeoutPerShutdownPhase;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTimeoutPerShutdownPhase(Duration timeoutPerShutdownPhase) {
|
||||||
|
this.timeoutPerShutdownPhase = timeoutPerShutdownPhase;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -26,6 +26,7 @@ org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration,\
|
||||||
org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration,\
|
org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration,\
|
||||||
org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration,\
|
org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration,\
|
||||||
org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration,\
|
org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration,\
|
||||||
|
org.springframework.boot.autoconfigure.context.LifecycleAutoConfiguration,\
|
||||||
org.springframework.boot.autoconfigure.context.MessageSourceAutoConfiguration,\
|
org.springframework.boot.autoconfigure.context.MessageSourceAutoConfiguration,\
|
||||||
org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration,\
|
org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration,\
|
||||||
org.springframework.boot.autoconfigure.couchbase.CouchbaseAutoConfiguration,\
|
org.springframework.boot.autoconfigure.couchbase.CouchbaseAutoConfiguration,\
|
||||||
|
|
|
@ -0,0 +1,79 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2012-2020 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.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.springframework.boot.autoconfigure.context;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||||
|
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.context.support.AbstractApplicationContext;
|
||||||
|
import org.springframework.context.support.DefaultLifecycleProcessor;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests for {@link LifecycleAutoConfiguration}.
|
||||||
|
*
|
||||||
|
* @author Andy Wilkinson
|
||||||
|
*/
|
||||||
|
public class LifecycleAutoConfigurationTests {
|
||||||
|
|
||||||
|
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
|
||||||
|
.withConfiguration(AutoConfigurations.of(LifecycleAutoConfiguration.class));
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void lifecycleProcessorIsConfiguredWithDefaultTimeout() {
|
||||||
|
this.contextRunner.run((context) -> {
|
||||||
|
assertThat(context).hasBean(AbstractApplicationContext.LIFECYCLE_PROCESSOR_BEAN_NAME);
|
||||||
|
Object processor = context.getBean(AbstractApplicationContext.LIFECYCLE_PROCESSOR_BEAN_NAME);
|
||||||
|
assertThat(processor).extracting("timeoutPerShutdownPhase").isEqualTo(30000L);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void lifecycleProcessorIsConfiguredWithCustomDefaultTimeout() {
|
||||||
|
this.contextRunner.withPropertyValues("spring.lifecycle.timeout-per-shutdown-phase=15s").run((context) -> {
|
||||||
|
assertThat(context).hasBean(AbstractApplicationContext.LIFECYCLE_PROCESSOR_BEAN_NAME);
|
||||||
|
Object processor = context.getBean(AbstractApplicationContext.LIFECYCLE_PROCESSOR_BEAN_NAME);
|
||||||
|
assertThat(processor).extracting("timeoutPerShutdownPhase").isEqualTo(15000L);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void whenUserDefinesALifecycleProcessorBeanThenTheAutoConfigurationBacksOff() {
|
||||||
|
this.contextRunner.withUserConfiguration(LifecycleProcessorConfiguration.class).run((context) -> {
|
||||||
|
assertThat(context).hasBean(AbstractApplicationContext.LIFECYCLE_PROCESSOR_BEAN_NAME);
|
||||||
|
Object processor = context.getBean(AbstractApplicationContext.LIFECYCLE_PROCESSOR_BEAN_NAME);
|
||||||
|
assertThat(processor).extracting("timeoutPerShutdownPhase").isEqualTo(5000L);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Configuration(proxyBeanMethods = false)
|
||||||
|
static class LifecycleProcessorConfiguration {
|
||||||
|
|
||||||
|
@Bean(name = AbstractApplicationContext.LIFECYCLE_PROCESSOR_BEAN_NAME)
|
||||||
|
DefaultLifecycleProcessor customLifecycleProcessor() {
|
||||||
|
DefaultLifecycleProcessor processor = new DefaultLifecycleProcessor();
|
||||||
|
processor.setTimeoutPerShutdownPhase(5000);
|
||||||
|
return processor;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -3160,6 +3160,13 @@ To enable graceful shutdown, configure the configprop:server.shutdown[] property
|
||||||
server.shutdown=graceful
|
server.shutdown=graceful
|
||||||
----
|
----
|
||||||
|
|
||||||
|
To configure the timeout period, configure the configprop:spring.lifecycle.timeout-per-shutdown-phase[] property, as shown in the following example:
|
||||||
|
|
||||||
|
[source,properties,indent=0,configprops]
|
||||||
|
----
|
||||||
|
spring.lifecycle.timeout-per-shutdown-phase=20s
|
||||||
|
----
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[[boot-features-rsocket]]
|
[[boot-features-rsocket]]
|
||||||
|
|
Loading…
Reference in New Issue