From 9e212875c3653b5b6e58fc4c7106b95bd332178c Mon Sep 17 00:00:00 2001 From: Moritz Halbritter Date: Fri, 28 Jul 2023 14:13:43 +0200 Subject: [PATCH] Remove VirtualThreads bean Reverts eeb1e1fc35267f5a200284a8390dccc10fc8b355 See gh-36615 See gh-36387 --- .../RabbitAnnotationDrivenConfiguration.java | 61 +++++++++++++------ .../autoconfigure/thread/VirtualThreads.java | 50 --------------- .../VirtualThreadsAutoConfiguration.java | 39 ------------ ...ot.autoconfigure.AutoConfiguration.imports | 1 - .../amqp/RabbitAutoConfigurationTests.java | 17 +++--- .../VirtualThreadsAutoConfigurationTests.java | 60 ------------------ .../thread/VirtualThreadsTests.java | 47 -------------- 7 files changed, 51 insertions(+), 224 deletions(-) delete mode 100644 spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/thread/VirtualThreads.java delete mode 100644 spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/thread/VirtualThreadsAutoConfiguration.java delete mode 100644 spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/thread/VirtualThreadsAutoConfigurationTests.java delete mode 100644 spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/thread/VirtualThreadsTests.java diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/amqp/RabbitAnnotationDrivenConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/amqp/RabbitAnnotationDrivenConfiguration.java index 2a81759aea..0a5331e144 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/amqp/RabbitAnnotationDrivenConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/amqp/RabbitAnnotationDrivenConfiguration.java @@ -30,15 +30,18 @@ import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.autoconfigure.thread.VirtualThreads; +import org.springframework.boot.autoconfigure.condition.ConditionalOnThreading; +import org.springframework.boot.autoconfigure.thread.Threading; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.core.task.VirtualThreadTaskExecutor; /** * Configuration for Spring AMQP annotation driven endpoints. * * @author Stephane Nicoll * @author Josh Thornhill + * @author Moritz Halbritter */ @Configuration(proxyBeanMethods = false) @ConditionalOnClass(EnableRabbit.class) @@ -52,28 +55,28 @@ class RabbitAnnotationDrivenConfiguration { private final RabbitProperties properties; - private final ObjectProvider virtualThreads; - RabbitAnnotationDrivenConfiguration(ObjectProvider messageConverter, ObjectProvider messageRecoverer, - ObjectProvider retryTemplateCustomizers, RabbitProperties properties, - ObjectProvider virtualThreads) { + ObjectProvider retryTemplateCustomizers, RabbitProperties properties) { this.messageConverter = messageConverter; this.messageRecoverer = messageRecoverer; this.retryTemplateCustomizers = retryTemplateCustomizers; this.properties = properties; - this.virtualThreads = virtualThreads; } @Bean @ConditionalOnMissingBean + @ConditionalOnThreading(Threading.PLATFORM) SimpleRabbitListenerContainerFactoryConfigurer simpleRabbitListenerContainerFactoryConfigurer() { - SimpleRabbitListenerContainerFactoryConfigurer configurer = new SimpleRabbitListenerContainerFactoryConfigurer( - this.properties); - configurer.setMessageConverter(this.messageConverter.getIfUnique()); - configurer.setMessageRecoverer(this.messageRecoverer.getIfUnique()); - configurer.setRetryTemplateCustomizers(this.retryTemplateCustomizers.orderedStream().toList()); - this.virtualThreads.ifAvailable((virtualThreads) -> configurer.setTaskExecutor(virtualThreads.getExecutor())); + return simpleListenerConfigurer(); + } + + @Bean(name = "simpleRabbitListenerContainerFactoryConfigurer") + @ConditionalOnMissingBean + @ConditionalOnThreading(Threading.VIRTUAL) + SimpleRabbitListenerContainerFactoryConfigurer simpleRabbitListenerContainerFactoryConfigurerVirtualThreads() { + SimpleRabbitListenerContainerFactoryConfigurer configurer = simpleListenerConfigurer(); + configurer.setTaskExecutor(new VirtualThreadTaskExecutor()); return configurer; } @@ -92,13 +95,17 @@ class RabbitAnnotationDrivenConfiguration { @Bean @ConditionalOnMissingBean + @ConditionalOnThreading(Threading.PLATFORM) DirectRabbitListenerContainerFactoryConfigurer directRabbitListenerContainerFactoryConfigurer() { - DirectRabbitListenerContainerFactoryConfigurer configurer = new DirectRabbitListenerContainerFactoryConfigurer( - this.properties); - configurer.setMessageConverter(this.messageConverter.getIfUnique()); - configurer.setMessageRecoverer(this.messageRecoverer.getIfUnique()); - configurer.setRetryTemplateCustomizers(this.retryTemplateCustomizers.orderedStream().toList()); - this.virtualThreads.ifAvailable((virtualThreads) -> configurer.setTaskExecutor(virtualThreads.getExecutor())); + return directListenerConfigurer(); + } + + @Bean(name = "directRabbitListenerContainerFactoryConfigurer") + @ConditionalOnMissingBean + @ConditionalOnThreading(Threading.VIRTUAL) + DirectRabbitListenerContainerFactoryConfigurer directRabbitListenerContainerFactoryConfigurerVirtualThreads() { + DirectRabbitListenerContainerFactoryConfigurer configurer = directListenerConfigurer(); + configurer.setTaskExecutor(new VirtualThreadTaskExecutor()); return configurer; } @@ -114,6 +121,24 @@ class RabbitAnnotationDrivenConfiguration { return factory; } + private SimpleRabbitListenerContainerFactoryConfigurer simpleListenerConfigurer() { + SimpleRabbitListenerContainerFactoryConfigurer configurer = new SimpleRabbitListenerContainerFactoryConfigurer( + this.properties); + configurer.setMessageConverter(this.messageConverter.getIfUnique()); + configurer.setMessageRecoverer(this.messageRecoverer.getIfUnique()); + configurer.setRetryTemplateCustomizers(this.retryTemplateCustomizers.orderedStream().toList()); + return configurer; + } + + private DirectRabbitListenerContainerFactoryConfigurer directListenerConfigurer() { + DirectRabbitListenerContainerFactoryConfigurer configurer = new DirectRabbitListenerContainerFactoryConfigurer( + this.properties); + configurer.setMessageConverter(this.messageConverter.getIfUnique()); + configurer.setMessageRecoverer(this.messageRecoverer.getIfUnique()); + configurer.setRetryTemplateCustomizers(this.retryTemplateCustomizers.orderedStream().toList()); + return configurer; + } + @Configuration(proxyBeanMethods = false) @EnableRabbit @ConditionalOnMissingBean(name = RabbitListenerConfigUtils.RABBIT_LISTENER_ANNOTATION_PROCESSOR_BEAN_NAME) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/thread/VirtualThreads.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/thread/VirtualThreads.java deleted file mode 100644 index db4fd60b66..0000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/thread/VirtualThreads.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright 2012-2023 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.thread; - -import java.lang.reflect.Method; -import java.util.concurrent.Executor; -import java.util.concurrent.Executors; - -import org.springframework.util.Assert; -import org.springframework.util.ReflectionUtils; - -/** - * Virtual thread support. - * - * @author Moritz Halbritter - * @since 3.2.0 - */ -public class VirtualThreads { - - private final Executor executor; - - VirtualThreads() { - Method method = ReflectionUtils.findMethod(Executors.class, "newVirtualThreadPerTaskExecutor"); - Assert.notNull(method, "Executors.newVirtualThreadPerTaskExecutor() method is missing"); - this.executor = (Executor) ReflectionUtils.invokeMethod(method, null); - } - - /** - * Returns the virtual thread executor. - * @return the virtual thread executor - */ - public Executor getExecutor() { - return this.executor; - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/thread/VirtualThreadsAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/thread/VirtualThreadsAutoConfiguration.java deleted file mode 100644 index b2936490e4..0000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/thread/VirtualThreadsAutoConfiguration.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2012-2023 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.thread; - -import org.springframework.boot.autoconfigure.AutoConfiguration; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.autoconfigure.condition.ConditionalOnVirtualThreads; -import org.springframework.context.annotation.Bean; - -/** - * {@link EnableAutoConfiguration Auto-configuration} for virtual threads. - * - * @author Moritz Halbritter - * @since 3.2.0 - */ -@AutoConfiguration -@ConditionalOnVirtualThreads -public class VirtualThreadsAutoConfiguration { - - @Bean - VirtualThreads virtualThreads() { - return new VirtualThreads(); - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-boot-project/spring-boot-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports index 46be5e5216..7bd25ab471 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -119,7 +119,6 @@ org.springframework.boot.autoconfigure.sql.init.SqlInitializationAutoConfigurati org.springframework.boot.autoconfigure.ssl.SslAutoConfiguration org.springframework.boot.autoconfigure.task.TaskExecutionAutoConfiguration org.springframework.boot.autoconfigure.task.TaskSchedulingAutoConfiguration -org.springframework.boot.autoconfigure.thread.VirtualThreadsAutoConfiguration org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration org.springframework.boot.autoconfigure.transaction.jta.JtaAutoConfiguration diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/amqp/RabbitAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/amqp/RabbitAutoConfigurationTests.java index afe3271b48..1d54051d73 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/amqp/RabbitAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/amqp/RabbitAutoConfigurationTests.java @@ -60,7 +60,6 @@ import org.springframework.amqp.rabbit.retry.MessageRecoverer; import org.springframework.amqp.support.converter.MessageConverter; import org.springframework.beans.factory.NoSuchBeanDefinitionException; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.thread.VirtualThreadsAutoConfiguration; import org.springframework.boot.test.context.assertj.AssertableApplicationContext; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.boot.test.system.CapturedOutput; @@ -71,6 +70,7 @@ import org.springframework.context.annotation.Import; import org.springframework.context.annotation.Primary; import org.springframework.core.Ordered; import org.springframework.core.annotation.Order; +import org.springframework.core.task.VirtualThreadTaskExecutor; import org.springframework.retry.RetryPolicy; import org.springframework.retry.backoff.BackOffPolicy; import org.springframework.retry.backoff.ExponentialBackOffPolicy; @@ -538,14 +538,13 @@ class RabbitAutoConfigurationTests { @Test @EnabledForJreRange(min = JRE.JAVA_21) void shouldConfigureVirtualThreads() { - this.contextRunner.withConfiguration(AutoConfigurations.of(VirtualThreadsAutoConfiguration.class)) - .withPropertyValues("spring.threads.virtual.enabled=true") - .run((context) -> { - SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory = context - .getBean("rabbitListenerContainerFactory", SimpleRabbitListenerContainerFactory.class); - Object executor = ReflectionTestUtils.getField(rabbitListenerContainerFactory, "taskExecutor"); - assertThat(executor).as("rabbitListenerContainerFactory.taskExecutor").isNotNull(); - }); + this.contextRunner.withPropertyValues("spring.threads.virtual.enabled=true").run((context) -> { + SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory = context + .getBean("rabbitListenerContainerFactory", SimpleRabbitListenerContainerFactory.class); + Object executor = ReflectionTestUtils.getField(rabbitListenerContainerFactory, "taskExecutor"); + assertThat(executor).as("rabbitListenerContainerFactory.taskExecutor") + .isInstanceOf(VirtualThreadTaskExecutor.class); + }); } @Test diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/thread/VirtualThreadsAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/thread/VirtualThreadsAutoConfigurationTests.java deleted file mode 100644 index 12d80789f9..0000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/thread/VirtualThreadsAutoConfigurationTests.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright 2012-2023 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.thread; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.condition.EnabledForJreRange; -import org.junit.jupiter.api.condition.JRE; - -import org.springframework.boot.autoconfigure.AutoConfiguration; -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.context.annotation.ImportCandidates; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link VirtualThreadsAutoConfiguration}. - * - * @author Moritz Halbritter - */ -class VirtualThreadsAutoConfigurationTests { - - private final ApplicationContextRunner runner = new ApplicationContextRunner() - .withConfiguration(AutoConfigurations.of(VirtualThreadsAutoConfiguration.class)); - - @Test - void shouldBeRegisteredInAutoConfigurationImports() { - assertThat(ImportCandidates.load(AutoConfiguration.class, null).getCandidates()) - .contains(VirtualThreadsAutoConfiguration.class.getName()); - } - - @Test - @EnabledForJreRange(min = JRE.JAVA_21) - void shouldSupplyBeans() { - this.runner.withPropertyValues("spring.threads.virtual.enabled=true") - .run((context) -> assertThat(context).hasSingleBean(VirtualThreads.class)); - } - - @Test - @EnabledForJreRange(min = JRE.JAVA_21) - void shouldNotSupplyBeansIfVirtualThreadsAreNotEnabled() { - this.runner.withPropertyValues("spring.threads.virtual.enabled=false") - .run((context) -> assertThat(context).doesNotHaveBean(VirtualThreads.class)); - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/thread/VirtualThreadsTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/thread/VirtualThreadsTests.java deleted file mode 100644 index 9f2bf4c40d..0000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/thread/VirtualThreadsTests.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2012-2023 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.thread; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.condition.EnabledForJreRange; -import org.junit.jupiter.api.condition.JRE; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; - -/** - * Tests for {@link VirtualThreads}. - * - * @author Moritz Halbritter - */ -class VirtualThreadsTests { - - @Test - @EnabledForJreRange(max = JRE.JAVA_20) - void shouldThrowExceptionBelowJava21() { - assertThatThrownBy(VirtualThreads::new).isInstanceOf(IllegalArgumentException.class) - .hasMessage("Executors.newVirtualThreadPerTaskExecutor() method is missing"); - } - - @Test - @EnabledForJreRange(min = JRE.JAVA_21) - void shouldReturnExecutorOnJava21AndUp() { - VirtualThreads virtualThreads = new VirtualThreads(); - assertThat(virtualThreads.getExecutor()).isNotNull(); - } - -}