Merge pull request #44134 from nosan

* pr/44134:
  Destroy WebServer if ReactiveWebServerApplicationContext refresh fails

Closes gh-44134
This commit is contained in:
Stéphane Nicoll 2025-02-17 10:53:39 +01:00
commit 6f05926643
2 changed files with 26 additions and 7 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2025 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.
@ -66,9 +66,10 @@ public class ReactiveWebServerApplicationContext extends GenericReactiveWebAppli
super.refresh();
}
catch (RuntimeException ex) {
WebServerManager serverManager = this.serverManager;
if (serverManager != null) {
serverManager.getWebServer().stop();
WebServer webServer = getWebServer();
if (webServer != null) {
webServer.stop();
webServer.destroy();
}
throw ex;
}
@ -147,6 +148,10 @@ public class ReactiveWebServerApplicationContext extends GenericReactiveWebAppli
AvailabilityChangeEvent.publish(this, ReadinessState.REFUSING_TRAFFIC);
}
super.doClose();
WebServer webServer = getWebServer();
if (webServer != null) {
webServer.destroy();
}
}
/**

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2024 the original author or authors.
* Copyright 2012-2025 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.
@ -30,6 +30,7 @@ import org.springframework.boot.availability.AvailabilityChangeEvent;
import org.springframework.boot.availability.ReadinessState;
import org.springframework.boot.web.context.ServerPortInfoApplicationContextInitializer;
import org.springframework.boot.web.reactive.server.MockReactiveWebServerFactory;
import org.springframework.boot.web.server.WebServer;
import org.springframework.context.ApplicationContextException;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
@ -42,6 +43,7 @@ import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
import static org.mockito.BDDMockito.then;
import static org.mockito.Mockito.times;
/**
* Tests for {@link ReactiveWebServerApplicationContext}.
@ -121,13 +123,25 @@ class ReactiveWebServerApplicationContextTests {
}
@Test
void whenContextIsClosedThenWebServerIsStopped() {
void whenContextRefreshFailedThenWebServerIsStoppedAndDestroyed() {
addWebServerFactoryBean();
addHttpHandlerBean();
this.context.registerBeanDefinition("refreshFailure", new RootBeanDefinition(RefreshFailure.class));
assertThatExceptionOfType(BeanCreationException.class).isThrownBy(this.context::refresh);
WebServer webServer = this.context.getWebServer();
then(webServer).should(times(2)).stop();
then(webServer).should().destroy();
}
@Test
void whenContextIsClosedThenWebServerIsStoppedAndDestroyed() {
addWebServerFactoryBean();
addHttpHandlerBean();
this.context.refresh();
MockReactiveWebServerFactory factory = this.context.getBean(MockReactiveWebServerFactory.class);
this.context.close();
then(factory.getWebServer()).should().stop();
then(factory.getWebServer()).should(times(2)).stop();
then(factory.getWebServer()).should().destroy();
}
@Test