diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/embedded/TomcatWebServerFactoryCustomizer.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/embedded/TomcatWebServerFactoryCustomizer.java index 2976b2d5edc..8699299ee8b 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/embedded/TomcatWebServerFactoryCustomizer.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/embedded/TomcatWebServerFactoryCustomizer.java @@ -21,10 +21,7 @@ import java.util.List; import java.util.function.ObjIntConsumer; import java.util.stream.Collectors; -import javax.management.ObjectName; - import org.apache.catalina.Lifecycle; -import org.apache.catalina.core.StandardThreadExecutor; import org.apache.catalina.valves.AccessLogValve; import org.apache.catalina.valves.ErrorReportValve; import org.apache.catalina.valves.RemoteIpValve; @@ -39,7 +36,6 @@ import org.springframework.boot.autoconfigure.web.ErrorProperties.IncludeAttribu import org.springframework.boot.autoconfigure.web.ServerProperties; import org.springframework.boot.autoconfigure.web.ServerProperties.Tomcat.Accesslog; import org.springframework.boot.autoconfigure.web.ServerProperties.Tomcat.Remoteip; -import org.springframework.boot.autoconfigure.web.ServerProperties.Tomcat.Threads; import org.springframework.boot.cloud.CloudPlatform; import org.springframework.boot.context.properties.PropertyMapper; import org.springframework.boot.web.embedded.tomcat.ConfigurableTomcatWebServerFactory; @@ -98,7 +94,16 @@ public class TomcatWebServerFactoryCustomizer .as(Long::intValue) .to(factory::setBackgroundProcessorDelay); customizeRemoteIpValve(factory); - configureExecutor(factory, properties.getThreads()); + ServerProperties.Tomcat.Threads threadProperties = properties.getThreads(); + map.from(threadProperties::getMax) + .when(this::isPositive) + .to((maxThreads) -> customizeMaxThreads(factory, maxThreads)); + map.from(threadProperties::getMinSpare) + .when(this::isPositive) + .to((minSpareThreads) -> customizeMinThreads(factory, minSpareThreads)); + map.from(threadProperties::getMaxQueueCapacity) + .when(this::isPositive) + .to((maxQueueCapacity) -> customizeMaxQueueCapacity(factory, maxQueueCapacity)); map.from(this.serverProperties.getMaxHttpRequestHeaderSize()) .asInt(DataSize::toBytes) .when(this::isPositive) @@ -146,23 +151,25 @@ public class TomcatWebServerFactoryCustomizer customizeErrorReportValve(this.serverProperties.getError(), factory); } - private void configureExecutor(ConfigurableTomcatWebServerFactory factory, Threads threadProperties) { - factory.addProtocolHandlerCustomizers((handler) -> { - StandardThreadExecutor executor = new StandardThreadExecutor(); - executor.setMinSpareThreads(threadProperties.getMinSpare()); - executor.setMaxThreads(threadProperties.getMax()); - executor.setMaxQueueSize(threadProperties.getMaxQueueCapacity()); - if (handler instanceof AbstractProtocol protocol) { - executor.setNamePrefix(ObjectName.unquote(protocol.getName()) + "-exec-"); - } - handler.setExecutor(executor); - }); - } - private boolean isPositive(int value) { return value > 0; } + @SuppressWarnings("rawtypes") + private void customizeMaxThreads(ConfigurableTomcatWebServerFactory factory, int maxThreads) { + customizeHandler(factory, maxThreads, AbstractProtocol.class, AbstractProtocol::setMaxThreads); + } + + @SuppressWarnings("rawtypes") + private void customizeMinThreads(ConfigurableTomcatWebServerFactory factory, int minSpareThreads) { + customizeHandler(factory, minSpareThreads, AbstractProtocol.class, AbstractProtocol::setMinSpareThreads); + } + + @SuppressWarnings("rawtypes") + private void customizeMaxQueueCapacity(ConfigurableTomcatWebServerFactory factory, int maxQueueCapacity) { + customizeHandler(factory, maxQueueCapacity, AbstractProtocol.class, AbstractProtocol::setMaxQueueSize); + } + @SuppressWarnings("rawtypes") private void customizeAcceptCount(ConfigurableTomcatWebServerFactory factory, int acceptCount) { customizeHandler(factory, acceptCount, AbstractProtocol.class, AbstractProtocol::setAcceptCount); diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/embedded/TomcatWebServerFactoryCustomizerTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/embedded/TomcatWebServerFactoryCustomizerTests.java index 205d98db53d..f3c1ed49304 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/embedded/TomcatWebServerFactoryCustomizerTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/embedded/TomcatWebServerFactoryCustomizerTests.java @@ -17,12 +17,10 @@ package org.springframework.boot.autoconfigure.web.embedded; import java.util.Locale; -import java.util.concurrent.Executor; import java.util.function.Consumer; import org.apache.catalina.Context; import org.apache.catalina.Valve; -import org.apache.catalina.core.StandardThreadExecutor; import org.apache.catalina.startup.Tomcat; import org.apache.catalina.valves.AccessLogValve; import org.apache.catalina.valves.ErrorReportValve; @@ -572,12 +570,10 @@ class TomcatWebServerFactoryCustomizerTests { bind("server.tomcat.threads.max=10", "server.tomcat.threads.min-spare=2", "server.tomcat.threads.max-queue-capacity=20"); customizeAndRunServer((server) -> { - Executor executor = server.getTomcat().getConnector().getProtocolHandler().getExecutor(); - assertThat(executor).isInstanceOf(StandardThreadExecutor.class); - StandardThreadExecutor standardThreadExecutor = (StandardThreadExecutor) executor; - assertThat(standardThreadExecutor.getMaxThreads()).isEqualTo(10); - assertThat(standardThreadExecutor.getMinSpareThreads()).isEqualTo(2); - assertThat(standardThreadExecutor.getMaxQueueSize()).isEqualTo(20); + AbstractProtocol protocol = (AbstractProtocol) server.getTomcat().getConnector().getProtocolHandler(); + assertThat(protocol.getMaxThreads()).isEqualTo(10); + assertThat(protocol.getMinSpareThreads()).isEqualTo(2); + assertThat(protocol.getMaxQueueSize()).isEqualTo(20); }); }