Provide a constant for graceful shutdown's smart lifecyle phase

In order to provide a single constant for graceful shutdown's smart
lifecycle, this commit replaces the package-private reactive and
servlet-specific implementations with a single public implementation
that can be used by both web stacks. This new public implementation
provides a constant for its smart lifecycle phase.

Closes gh-24255
This commit is contained in:
Andy Wilkinson 2021-03-19 17:56:14 +00:00
parent ca46fe7cd0
commit f0a8c02efd
5 changed files with 28 additions and 68 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2020 the original author or authors.
* Copyright 2012-2021 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.
@ -14,24 +14,35 @@
* limitations under the License.
*/
package org.springframework.boot.web.servlet.context;
package org.springframework.boot.web.context;
import org.springframework.boot.web.server.WebServer;
import org.springframework.context.SmartLifecycle;
/**
* {@link SmartLifecycle} to trigger {@link WebServer} graceful shutdown in a
* {@link ServletWebServerApplicationContext}.
* {@link SmartLifecycle} to trigger {@link WebServer} graceful shutdown.
*
* @author Andy Wilkinson
* @since 2.5.0
*/
class WebServerGracefulShutdownLifecycle implements SmartLifecycle {
public final class WebServerGracefulShutdownLifecycle implements SmartLifecycle {
/**
* {@link SmartLifecycle#getPhase() SmartLifecycle phase} in which graceful shutdown
* of the web server is performed.
*/
public static final int SMART_LIFECYCLE_PHASE = SmartLifecycle.DEFAULT_PHASE;
private final WebServer webServer;
private volatile boolean running;
WebServerGracefulShutdownLifecycle(WebServer webServer) {
/**
* Creates a new {@code WebServerGracefulShutdownLifecycle} that will gracefully shut
* down the given {@code webServer}.
* @param webServer web server to shut down gracefully
*/
public WebServerGracefulShutdownLifecycle(WebServer webServer) {
this.webServer = webServer;
}
@ -56,4 +67,9 @@ class WebServerGracefulShutdownLifecycle implements SmartLifecycle {
return this.running;
}
@Override
public int getPhase() {
return SMART_LIFECYCLE_PHASE;
}
}

View File

@ -21,6 +21,7 @@ import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.boot.availability.AvailabilityChangeEvent;
import org.springframework.boot.availability.ReadinessState;
import org.springframework.boot.web.context.ConfigurableWebServerApplicationContext;
import org.springframework.boot.web.context.WebServerGracefulShutdownLifecycle;
import org.springframework.boot.web.reactive.server.ReactiveWebServerFactory;
import org.springframework.boot.web.server.WebServer;
import org.springframework.context.ApplicationContextException;
@ -92,7 +93,7 @@ public class ReactiveWebServerApplicationContext extends GenericReactiveWebAppli
boolean lazyInit = getBeanFactory().getBeanDefinition(webServerFactoryBeanName).isLazyInit();
this.serverManager = new WebServerManager(this, webServerFactory, this::getHttpHandler, lazyInit);
getBeanFactory().registerSingleton("webServerGracefulShutdown",
new WebServerGracefulShutdownLifecycle(this.serverManager));
new WebServerGracefulShutdownLifecycle(this.serverManager.getWebServer()));
getBeanFactory().registerSingleton("webServerStartStop",
new WebServerStartStopLifecycle(this.serverManager));
createWebServer.end();

View File

@ -1,59 +0,0 @@
/*
* 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.web.reactive.context;
import org.springframework.boot.web.server.WebServer;
import org.springframework.context.SmartLifecycle;
/**
* {@link SmartLifecycle} to trigger {@link WebServer} graceful shutdown in a
* {@link ReactiveWebServerApplicationContext}.
*
* @author Andy Wilkinson
*/
class WebServerGracefulShutdownLifecycle implements SmartLifecycle {
private final WebServerManager serverManager;
private volatile boolean running;
WebServerGracefulShutdownLifecycle(WebServerManager serverManager) {
this.serverManager = serverManager;
}
@Override
public void start() {
this.running = true;
}
@Override
public void stop() {
throw new UnsupportedOperationException("Stop must not be invoked directly");
}
@Override
public void stop(Runnable callback) {
this.running = false;
this.serverManager.shutDownGracefully(callback);
}
@Override
public boolean isRunning() {
return this.running;
}
}

View File

@ -21,6 +21,7 @@ import java.util.function.Supplier;
import reactor.core.publisher.Mono;
import org.springframework.boot.web.reactive.server.ReactiveWebServerFactory;
import org.springframework.boot.web.server.GracefulShutdownCallback;
import org.springframework.boot.web.server.WebServer;
import org.springframework.http.server.reactive.HttpHandler;
import org.springframework.http.server.reactive.ServerHttpRequest;
@ -56,8 +57,8 @@ class WebServerManager {
.publishEvent(new ReactiveWebServerInitializedEvent(this.webServer, this.applicationContext));
}
void shutDownGracefully(Runnable callback) {
this.webServer.shutDownGracefully((result) -> callback.run());
void shutDownGracefully(GracefulShutdownCallback callback) {
this.webServer.shutDownGracefully(callback);
}
void stop() {

View File

@ -40,6 +40,7 @@ import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.boot.availability.AvailabilityChangeEvent;
import org.springframework.boot.availability.ReadinessState;
import org.springframework.boot.web.context.ConfigurableWebServerApplicationContext;
import org.springframework.boot.web.context.WebServerGracefulShutdownLifecycle;
import org.springframework.boot.web.server.WebServer;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletContextInitializer;