diff --git a/module/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/autoconfigure/JettyServerProperties.java b/module/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/autoconfigure/JettyServerProperties.java index c4678b4630c..cf6ab922c91 100644 --- a/module/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/autoconfigure/JettyServerProperties.java +++ b/module/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/autoconfigure/JettyServerProperties.java @@ -286,8 +286,7 @@ public class JettyServerProperties { private Integer selectors = -1; /** - * Maximum number of threads. Doesn't have an effect if virtual threads are - * enabled. + * Maximum number of threads. */ private Integer max = 200; diff --git a/module/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/autoconfigure/JettyVirtualThreadsWebServerFactoryCustomizer.java b/module/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/autoconfigure/JettyVirtualThreadsWebServerFactoryCustomizer.java index 1eb65770766..2bf589296a5 100644 --- a/module/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/autoconfigure/JettyVirtualThreadsWebServerFactoryCustomizer.java +++ b/module/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/autoconfigure/JettyVirtualThreadsWebServerFactoryCustomizer.java @@ -18,8 +18,10 @@ package org.springframework.boot.jetty.autoconfigure; import org.eclipse.jetty.util.VirtualThreads; import org.eclipse.jetty.util.thread.VirtualThreadPool; +import org.jspecify.annotations.Nullable; import org.springframework.boot.jetty.ConfigurableJettyWebServerFactory; +import org.springframework.boot.jetty.autoconfigure.JettyServerProperties.Threads; import org.springframework.boot.web.server.WebServerFactoryCustomizer; import org.springframework.core.Ordered; import org.springframework.util.Assert; @@ -34,11 +36,39 @@ import org.springframework.util.Assert; public class JettyVirtualThreadsWebServerFactoryCustomizer implements WebServerFactoryCustomizer, Ordered { + private final @Nullable JettyServerProperties serverProperties; + + /** + * Create a new JettyVirtualThreadsWebServerFactoryCustomizer. + * @deprecated since 4.0.3 for removal in 4.3.0 in favor of + * {@link #JettyVirtualThreadsWebServerFactoryCustomizer(JettyServerProperties)} + */ + @Deprecated(since = "4.0.3", forRemoval = true) + // Suppress the null passing here as we don't want to put @Nullable on the + // JettyServerProperties in the other constructor + @SuppressWarnings("NullAway") + public JettyVirtualThreadsWebServerFactoryCustomizer() { + this(null); + } + + /** + * Create a new JettyVirtualThreadsWebServerFactoryCustomizer. + * @param serverProperties the server properties + */ + public JettyVirtualThreadsWebServerFactoryCustomizer(JettyServerProperties serverProperties) { + this.serverProperties = serverProperties; + } + @Override public void customize(ConfigurableJettyWebServerFactory factory) { Assert.state(VirtualThreads.areSupported(), "Virtual threads are not supported"); VirtualThreadPool virtualThreadPool = new VirtualThreadPool(); virtualThreadPool.setName("jetty-"); + if (this.serverProperties != null) { + Threads properties = this.serverProperties.getThreads(); + int maxThreadCount = (properties.getMax() > 0) ? properties.getMax() : 200; + virtualThreadPool.setMaxThreads(maxThreadCount); + } factory.setThreadPool(virtualThreadPool); } diff --git a/module/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/autoconfigure/JettyWebServerConfiguration.java b/module/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/autoconfigure/JettyWebServerConfiguration.java index 9a0e0ab1411..08d6b746b6b 100644 --- a/module/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/autoconfigure/JettyWebServerConfiguration.java +++ b/module/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/autoconfigure/JettyWebServerConfiguration.java @@ -38,16 +38,22 @@ import org.springframework.core.env.Environment; @Configuration(proxyBeanMethods = false) public class JettyWebServerConfiguration { + private final JettyServerProperties jettyProperties; + + JettyWebServerConfiguration(JettyServerProperties jettyProperties) { + this.jettyProperties = jettyProperties; + } + @Bean JettyWebServerFactoryCustomizer jettyWebServerFactoryCustomizer(Environment environment, - ServerProperties serverProperties, JettyServerProperties jettyProperties) { - return new JettyWebServerFactoryCustomizer(environment, serverProperties, jettyProperties); + ServerProperties serverProperties) { + return new JettyWebServerFactoryCustomizer(environment, serverProperties, this.jettyProperties); } @Bean @ConditionalOnThreading(Threading.VIRTUAL) JettyVirtualThreadsWebServerFactoryCustomizer jettyVirtualThreadsWebServerFactoryCustomizer() { - return new JettyVirtualThreadsWebServerFactoryCustomizer(); + return new JettyVirtualThreadsWebServerFactoryCustomizer(this.jettyProperties); } } diff --git a/module/spring-boot-jetty/src/test/java/org/springframework/boot/jetty/autoconfigure/JettyVirtualThreadsWebServerFactoryCustomizerTests.java b/module/spring-boot-jetty/src/test/java/org/springframework/boot/jetty/autoconfigure/JettyVirtualThreadsWebServerFactoryCustomizerTests.java index d7c41dd9832..c5d31db9b4e 100644 --- a/module/spring-boot-jetty/src/test/java/org/springframework/boot/jetty/autoconfigure/JettyVirtualThreadsWebServerFactoryCustomizerTests.java +++ b/module/spring-boot-jetty/src/test/java/org/springframework/boot/jetty/autoconfigure/JettyVirtualThreadsWebServerFactoryCustomizerTests.java @@ -38,13 +38,17 @@ class JettyVirtualThreadsWebServerFactoryCustomizerTests { @Test @EnabledForJreRange(min = JRE.JAVA_21) void shouldConfigureVirtualThreads() { - JettyVirtualThreadsWebServerFactoryCustomizer customizer = new JettyVirtualThreadsWebServerFactoryCustomizer(); + JettyServerProperties serverProperties = new JettyServerProperties(); + serverProperties.getThreads().setMax(100); + JettyVirtualThreadsWebServerFactoryCustomizer customizer = new JettyVirtualThreadsWebServerFactoryCustomizer( + serverProperties); ConfigurableJettyWebServerFactory factory = mock(ConfigurableJettyWebServerFactory.class); customizer.customize(factory); then(factory).should().setThreadPool(assertArg((threadPool) -> { assertThat(threadPool).isInstanceOf(VirtualThreadPool.class); VirtualThreadPool virtualThreadPool = (VirtualThreadPool) threadPool; assertThat(virtualThreadPool.getName()).isEqualTo("jetty-"); + assertThat(virtualThreadPool.getMaxThreads()).isEqualTo(100); })); }