diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/condition/ConditionalOnNotWarDeployment.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/condition/ConditionalOnNotWarDeployment.java index 0d8387274e46..f51704c8092e 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/condition/ConditionalOnNotWarDeployment.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/condition/ConditionalOnNotWarDeployment.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2023 the original author or authors. + * Copyright 2012-2024 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. @@ -31,11 +31,15 @@ * * @author Guirong Hu * @since 2.7.10 + * @deprecated since 3.4.0 in favor of + * {@link org.springframework.boot.autoconfigure.web.servlet.ConditionalOnNotWarDeployment} */ @Target({ ElementType.TYPE, ElementType.METHOD }) @Retention(RetentionPolicy.RUNTIME) @Documented @Conditional(OnWarDeploymentCondition.class) +@Deprecated(since = "3.4.0", forRemoval = true) +@SuppressWarnings("removal") public @interface ConditionalOnNotWarDeployment { } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/condition/ConditionalOnWarDeployment.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/condition/ConditionalOnWarDeployment.java index 7afa6cfaf766..c7842aaa8a0f 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/condition/ConditionalOnWarDeployment.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/condition/ConditionalOnWarDeployment.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2020 the original author or authors. + * Copyright 2012-2024 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,11 +30,15 @@ * * @author Madhura Bhave * @since 2.3.0 + * @deprecated since 3.4.0 in favor of + * {@link org.springframework.boot.autoconfigure.web.servlet.ConditionalOnWarDeployment} */ @Target({ ElementType.TYPE, ElementType.METHOD }) @Retention(RetentionPolicy.RUNTIME) @Documented @Conditional(OnWarDeploymentCondition.class) +@Deprecated(since = "3.4.0", forRemoval = true) +@SuppressWarnings("removal") public @interface ConditionalOnWarDeployment { } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/condition/OnWarDeploymentCondition.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/condition/OnWarDeploymentCondition.java index 5393d4b63b20..c8c1c11168b1 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/condition/OnWarDeploymentCondition.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/condition/OnWarDeploymentCondition.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2023 the original author or authors. + * Copyright 2012-2024 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. @@ -32,6 +32,8 @@ * @see ConditionalOnWarDeployment * @see ConditionalOnNotWarDeployment */ +@Deprecated(since = "3.4.0", forRemoval = true) +@SuppressWarnings("removal") class OnWarDeploymentCondition extends SpringBootCondition { @Override diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/embedded/EmbeddedWebServerFactoryCustomizerAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/embedded/EmbeddedWebServerFactoryCustomizerAutoConfiguration.java index 0c1ea3964f22..c32f931ae226 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/embedded/EmbeddedWebServerFactoryCustomizerAutoConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/embedded/EmbeddedWebServerFactoryCustomizerAutoConfiguration.java @@ -28,11 +28,11 @@ import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnNotWarDeployment; import org.springframework.boot.autoconfigure.condition.ConditionalOnThreading; import org.springframework.boot.autoconfigure.thread.Threading; import org.springframework.boot.autoconfigure.web.ConditionalOnWebApplication; import org.springframework.boot.autoconfigure.web.ServerProperties; +import org.springframework.boot.autoconfigure.web.servlet.ConditionalOnNotWarDeployment; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/ConditionalOnNotWarDeployment.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/ConditionalOnNotWarDeployment.java new file mode 100644 index 000000000000..9d153711ed4d --- /dev/null +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/ConditionalOnNotWarDeployment.java @@ -0,0 +1,41 @@ +/* + * Copyright 2012-2024 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.web.servlet; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import org.springframework.context.annotation.Conditional; + +/** + * {@link Conditional @Conditional} that only matches when the application is not a + * traditional WAR deployment. For applications with embedded servers, this condition will + * return true. + * + * @author Guirong Hu + * @since 3.4.0 + */ +@Target({ ElementType.TYPE, ElementType.METHOD }) +@Retention(RetentionPolicy.RUNTIME) +@Documented +@Conditional(OnWarDeploymentCondition.class) +public @interface ConditionalOnNotWarDeployment { + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/ConditionalOnWarDeployment.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/ConditionalOnWarDeployment.java new file mode 100644 index 000000000000..8d55ec443cdf --- /dev/null +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/ConditionalOnWarDeployment.java @@ -0,0 +1,40 @@ +/* + * Copyright 2012-2024 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.web.servlet; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import org.springframework.context.annotation.Conditional; + +/** + * {@link Conditional @Conditional} that matches when the application is a traditional WAR + * deployment. For applications with embedded servers, this condition will return false. + * + * @author Madhura Bhave + * @since 3.4.0 + */ +@Target({ ElementType.TYPE, ElementType.METHOD }) +@Retention(RetentionPolicy.RUNTIME) +@Documented +@Conditional(OnWarDeploymentCondition.class) +public @interface ConditionalOnWarDeployment { + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/OnWarDeploymentCondition.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/OnWarDeploymentCondition.java new file mode 100644 index 000000000000..4d909f0c3fb3 --- /dev/null +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/OnWarDeploymentCondition.java @@ -0,0 +1,54 @@ +/* + * Copyright 2012-2024 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.web.servlet; + +import jakarta.servlet.ServletContext; + +import org.springframework.boot.autoconfigure.condition.ConditionMessage; +import org.springframework.boot.autoconfigure.condition.ConditionOutcome; +import org.springframework.boot.autoconfigure.condition.SpringBootCondition; +import org.springframework.context.annotation.Condition; +import org.springframework.context.annotation.ConditionContext; +import org.springframework.core.io.ResourceLoader; +import org.springframework.core.type.AnnotatedTypeMetadata; +import org.springframework.web.context.WebApplicationContext; + +/** + * {@link Condition} that checks if the application is running as a traditional war + * deployment. + * + * @author Madhura Bhave + * @see ConditionalOnWarDeployment + * @see ConditionalOnNotWarDeployment + */ +class OnWarDeploymentCondition extends SpringBootCondition { + + @Override + public ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeMetadata metadata) { + boolean required = metadata.isAnnotated(ConditionalOnWarDeployment.class.getName()); + ResourceLoader resourceLoader = context.getResourceLoader(); + if (resourceLoader instanceof WebApplicationContext applicationContext) { + ServletContext servletContext = applicationContext.getServletContext(); + if (servletContext != null) { + return new ConditionOutcome(required, "Application is deployed as a WAR file."); + } + } + return new ConditionOutcome(!required, ConditionMessage.forCondition(ConditionalOnWarDeployment.class) + .because("the application is not deployed as a WAR file.")); + } + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/websocket/servlet/WebSocketServletAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/websocket/servlet/WebSocketServletAutoConfiguration.java index 6d78836e3209..dc1b60582226 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/websocket/servlet/WebSocketServletAutoConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/websocket/servlet/WebSocketServletAutoConfiguration.java @@ -30,9 +30,9 @@ import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnNotWarDeployment; import org.springframework.boot.autoconfigure.web.ConditionalOnWebApplication; import org.springframework.boot.autoconfigure.web.ConditionalOnWebApplication.Type; +import org.springframework.boot.autoconfigure.web.servlet.ConditionalOnNotWarDeployment; import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration; import org.springframework.boot.web.embedded.jetty.JettyServletWebServerFactory; import org.springframework.boot.web.server.WebServerFactoryCustomizer; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/condition/ConditionalOnNotWarDeploymentTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/condition/ConditionalOnNotWarDeploymentTests.java index d713aa146b45..766abeff1db6 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/condition/ConditionalOnNotWarDeploymentTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/condition/ConditionalOnNotWarDeploymentTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2023 the original author or authors. + * Copyright 2012-2024 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. @@ -32,6 +32,8 @@ * * @author Guirong Hu */ +@Deprecated(since = "3.4.0") +@SuppressWarnings("removal") class ConditionalOnNotWarDeploymentTests { @Test diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/condition/ConditionalOnWarDeploymentTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/condition/ConditionalOnWarDeploymentTests.java index c3507f9bcf1e..618350367139 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/condition/ConditionalOnWarDeploymentTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/condition/ConditionalOnWarDeploymentTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2023 the original author or authors. + * Copyright 2012-2024 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. @@ -32,6 +32,8 @@ * * @author Madhura Bhave */ +@Deprecated(since = "3.4.0") +@SuppressWarnings("removal") class ConditionalOnWarDeploymentTests { @Test diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/ConditionalOnNotWarDeploymentTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/ConditionalOnNotWarDeploymentTests.java new file mode 100644 index 000000000000..fa96b7ce44da --- /dev/null +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/ConditionalOnNotWarDeploymentTests.java @@ -0,0 +1,77 @@ +/* + * Copyright 2012-2024 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.web.servlet; + +import org.junit.jupiter.api.Test; + +import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner; +import org.springframework.boot.test.context.runner.WebApplicationContextRunner; +import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link ConditionalOnNotWarDeployment @ConditionalOnNotWarDeployment}. + * + * @author Guirong Hu + */ +class ConditionalOnNotWarDeploymentTests { + + @Test + void nonWebApplicationShouldMatch() { + ApplicationContextRunner contextRunner = new ApplicationContextRunner(); + contextRunner.withUserConfiguration(NotWarDeploymentConfiguration.class) + .run((context) -> assertThat(context).hasBean("notForWar")); + } + + @Test + void reactiveWebApplicationShouldMatch() { + ReactiveWebApplicationContextRunner contextRunner = new ReactiveWebApplicationContextRunner(); + contextRunner.withUserConfiguration(NotWarDeploymentConfiguration.class) + .run((context) -> assertThat(context).hasBean("notForWar")); + } + + @Test + void embeddedServletWebApplicationShouldMatch() { + WebApplicationContextRunner contextRunner = new WebApplicationContextRunner( + AnnotationConfigServletWebApplicationContext::new); + contextRunner.withUserConfiguration(NotWarDeploymentConfiguration.class) + .run((context) -> assertThat(context).hasBean("notForWar")); + } + + @Test + void warDeployedServletWebApplicationShouldNotMatch() { + WebApplicationContextRunner contextRunner = new WebApplicationContextRunner(); + contextRunner.withUserConfiguration(NotWarDeploymentConfiguration.class) + .run((context) -> assertThat(context).doesNotHaveBean("notForWar")); + } + + @Configuration(proxyBeanMethods = false) + @ConditionalOnNotWarDeployment + static class NotWarDeploymentConfiguration { + + @Bean + String notForWar() { + return "notForWar"; + } + + } + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/ConditionalOnWarDeploymentTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/ConditionalOnWarDeploymentTests.java new file mode 100644 index 000000000000..28e13ece9cbc --- /dev/null +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/ConditionalOnWarDeploymentTests.java @@ -0,0 +1,79 @@ +/* + * Copyright 2012-2024 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.web.servlet; + +import org.junit.jupiter.api.Test; + +import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner; +import org.springframework.boot.test.context.runner.WebApplicationContextRunner; +import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link ConditionalOnWarDeployment @ConditionalOnWarDeployment}. + * + * @author Madhura Bhave + */ +class ConditionalOnWarDeploymentTests { + + @Test + void nonWebApplicationShouldNotMatch() { + ApplicationContextRunner contextRunner = new ApplicationContextRunner(); + contextRunner.withUserConfiguration(TestConfiguration.class) + .run((context) -> assertThat(context).doesNotHaveBean("forWar")); + } + + @Test + void reactiveWebApplicationShouldNotMatch() { + ReactiveWebApplicationContextRunner contextRunner = new ReactiveWebApplicationContextRunner(); + contextRunner.withUserConfiguration(TestConfiguration.class) + .run((context) -> assertThat(context).doesNotHaveBean("forWar")); + } + + @Test + void embeddedServletWebApplicationShouldNotMatch() { + WebApplicationContextRunner contextRunner = new WebApplicationContextRunner( + AnnotationConfigServletWebApplicationContext::new); + contextRunner.withUserConfiguration(TestConfiguration.class) + .run((context) -> assertThat(context).doesNotHaveBean("forWar")); + } + + @Test + void warDeployedServletWebApplicationShouldMatch() { + // sets a mock servletContext before context refresh which is what the + // SpringBootServletInitializer does for WAR deployments. + WebApplicationContextRunner contextRunner = new WebApplicationContextRunner(); + contextRunner.withUserConfiguration(TestConfiguration.class) + .run((context) -> assertThat(context).hasBean("forWar")); + } + + @Configuration(proxyBeanMethods = false) + @ConditionalOnWarDeployment + static class TestConfiguration { + + @Bean + String forWar() { + return "forWar"; + } + + } + +} diff --git a/spring-boot-system-tests/spring-boot-deployment-tests/src/main/java/sample/autoconfig/ExampleAutoConfiguration.java b/spring-boot-system-tests/spring-boot-deployment-tests/src/main/java/sample/autoconfig/ExampleAutoConfiguration.java index ab6e9de1fc7e..4912593a08f6 100644 --- a/spring-boot-system-tests/spring-boot-deployment-tests/src/main/java/sample/autoconfig/ExampleAutoConfiguration.java +++ b/spring-boot-system-tests/spring-boot-deployment-tests/src/main/java/sample/autoconfig/ExampleAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2024 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. @@ -19,7 +19,7 @@ import org.springframework.boot.actuate.endpoint.annotation.Endpoint; import org.springframework.boot.actuate.endpoint.annotation.ReadOperation; import org.springframework.boot.autoconfigure.AutoConfiguration; -import org.springframework.boot.autoconfigure.condition.ConditionalOnWarDeployment; +import org.springframework.boot.autoconfigure.web.servlet.ConditionalOnWarDeployment; import org.springframework.context.annotation.Bean; @ConditionalOnWarDeployment