diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/thymeleaf/ThymeleafAutoConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/thymeleaf/ThymeleafAutoConfiguration.java index 3c7f4080c96..385de509558 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/thymeleaf/ThymeleafAutoConfiguration.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/thymeleaf/ThymeleafAutoConfiguration.java @@ -33,6 +33,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; import org.springframework.boot.autoconfigure.template.TemplateLocation; +import org.springframework.boot.autoconfigure.web.ConditionalOnEnabledResourceChain; import org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.ApplicationContext; @@ -232,6 +233,7 @@ public class ThymeleafAutoConfiguration { @Bean @ConditionalOnMissingBean + @ConditionalOnEnabledResourceChain public ResourceUrlEncodingFilter resourceUrlEncodingFilter() { return new ResourceUrlEncodingFilter(); } diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/velocity/VelocityAutoConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/velocity/VelocityAutoConfiguration.java index b9bc294021b..e9ed1172fdf 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/velocity/VelocityAutoConfiguration.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/velocity/VelocityAutoConfiguration.java @@ -33,6 +33,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnNotWebAppli import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; import org.springframework.boot.autoconfigure.template.TemplateLocation; +import org.springframework.boot.autoconfigure.web.ConditionalOnEnabledResourceChain; import org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.web.servlet.view.velocity.EmbeddedVelocityViewResolver; @@ -137,6 +138,7 @@ public class VelocityAutoConfiguration { @Bean @ConditionalOnMissingBean + @ConditionalOnEnabledResourceChain public ResourceUrlEncodingFilter resourceUrlEncodingFilter() { return new ResourceUrlEncodingFilter(); } diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/ConditionalOnEnabledResourceChain.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/ConditionalOnEnabledResourceChain.java new file mode 100644 index 00000000000..079cd985fdd --- /dev/null +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/ConditionalOnEnabledResourceChain.java @@ -0,0 +1,39 @@ +/* + * Copyright 2012-2015 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 + * + * http://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; + +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} that checks whether or not the Spring resource handling chain is + * enabled. Matches if {@link ResourceProperties.Chain#getEnabled()} is {@code true}. + * + * @author Stephane Nicoll + * @since 1.3.0 + */ +@Target({ElementType.TYPE, ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +@Documented +@Conditional(OnEnabledResourceChainCondition.class) +public @interface ConditionalOnEnabledResourceChain { +} diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/OnEnabledResourceChainCondition.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/OnEnabledResourceChainCondition.java new file mode 100644 index 00000000000..83e0da38b3e --- /dev/null +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/OnEnabledResourceChainCondition.java @@ -0,0 +1,47 @@ +/* + * Copyright 2012-2015 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 + * + * http://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; + +import org.springframework.boot.autoconfigure.condition.ConditionOutcome; +import org.springframework.boot.autoconfigure.condition.SpringBootCondition; +import org.springframework.boot.bind.PropertySourcesPropertyValues; +import org.springframework.boot.bind.RelaxedDataBinder; +import org.springframework.context.annotation.Condition; +import org.springframework.context.annotation.ConditionContext; +import org.springframework.core.env.ConfigurableEnvironment; +import org.springframework.core.type.AnnotatedTypeMetadata; + +/** + * {@link Condition} that checks whether or not the Spring resource handling chain is + * enabled. + * + * @author Stephane Nicoll + */ +class OnEnabledResourceChainCondition extends SpringBootCondition { + + @Override + public ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeMetadata metadata) { + ConfigurableEnvironment environment = (ConfigurableEnvironment) context.getEnvironment(); + ResourceProperties resourceProperties = new ResourceProperties(); + RelaxedDataBinder binder = new RelaxedDataBinder(resourceProperties, "spring.resources"); + binder.bind(new PropertySourcesPropertyValues(environment.getPropertySources())); + + Boolean match = resourceProperties.getChain().getEnabled(); + return new ConditionOutcome(match, "Resource chain is " + (match ? "enabled" : "disabled" + ")")); + } + +} diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/ResourceProperties.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/ResourceProperties.java index d0278cd1177..deb2114f1f0 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/ResourceProperties.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/ResourceProperties.java @@ -173,7 +173,9 @@ public class ResourceProperties implements ResourceLoaderAware { private final Strategy strategy = new Strategy(); public Boolean getEnabled() { - return this.enabled; + return Boolean.TRUE.equals(this.enabled) + || getStrategy().getFixed().isEnabled() + || getStrategy().getContent().isEnabled(); } public void setEnabled(boolean enabled) { diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/WebMvcAutoConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/WebMvcAutoConfiguration.java index 4046d089eec..42aa4d0eb80 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/WebMvcAutoConfiguration.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/WebMvcAutoConfiguration.java @@ -256,9 +256,7 @@ public class WebMvcAutoConfiguration { private void registerResourceChain(ResourceHandlerRegistration registration) { ResourceProperties.Chain properties = this.resourceProperties.getChain(); - if (Boolean.TRUE.equals(properties.getEnabled()) - || properties.getStrategy().getFixed().isEnabled() - || properties.getStrategy().getContent().isEnabled()) { + if (properties.getEnabled()) { configureResourceChain(properties, registration.resourceChain(properties.isCache())); } diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/thymeleaf/ThymeleafAutoConfigurationTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/thymeleaf/ThymeleafAutoConfigurationTests.java index 761680083fd..57acc8da3cb 100644 --- a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/thymeleaf/ThymeleafAutoConfigurationTests.java +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/thymeleaf/ThymeleafAutoConfigurationTests.java @@ -196,10 +196,20 @@ public class ThymeleafAutoConfigurationTests { } @Test - public void registerResourceHandlingFilter() throws Exception { + public void registerResourceHandlingFilterDisabledByDefault() throws Exception { this.context.register(ThymeleafAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class); this.context.refresh(); + assertEquals(0, this.context.getBeansOfType(ResourceUrlEncodingFilter.class).size()); + } + + @Test + public void registerResourceHandlingFilterOnlyIfResourceChainIsEnabled() throws Exception { + this.context.register(ThymeleafAutoConfiguration.class, + PropertyPlaceholderAutoConfiguration.class); + EnvironmentTestUtils.addEnvironment(this.context, + "spring.resources.chain.enabled:true"); + this.context.refresh(); assertNotNull(this.context.getBean(ResourceUrlEncodingFilter.class)); } diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/velocity/VelocityAutoConfigurationTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/velocity/VelocityAutoConfigurationTests.java index 0949d649a81..6738ca12c67 100644 --- a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/velocity/VelocityAutoConfigurationTests.java +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/velocity/VelocityAutoConfigurationTests.java @@ -49,6 +49,7 @@ import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.instanceOf; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.notNullValue; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertThat; @@ -56,6 +57,7 @@ import static org.junit.Assert.assertThat; * Tests for {@link VelocityAutoConfiguration}. * * @author Andy Wilkinson + * @author Stephane Nicoll */ public class VelocityAutoConfigurationTests { @@ -189,8 +191,14 @@ public class VelocityAutoConfigurationTests { } @Test - public void registerResourceHandlingFilter() throws Exception { + public void registerResourceHandlingFilterDisabledByDefault() throws Exception { registerAndRefreshContext(); + assertEquals(0, this.context.getBeansOfType(ResourceUrlEncodingFilter.class).size()); + } + + @Test + public void registerResourceHandlingFilterOnlyIfResourceChainIsEnabled() throws Exception { + registerAndRefreshContext("spring.resources.chain.enabled:true"); assertNotNull(this.context.getBean(ResourceUrlEncodingFilter.class)); } diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/ConditionalOnEnabledResourceChainTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/ConditionalOnEnabledResourceChainTests.java new file mode 100644 index 00000000000..e097d96590c --- /dev/null +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/ConditionalOnEnabledResourceChainTests.java @@ -0,0 +1,92 @@ +/* + * Copyright 2012-2015 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 + * + * http://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; + +import org.junit.After; +import org.junit.Test; + +import org.springframework.boot.test.EnvironmentTestUtils; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +/** + * Tests for {@link ConditionalOnEnabledResourceChain}. + * + * @author Stephane Nicoll + */ +public class ConditionalOnEnabledResourceChainTests { + + private final AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); + + @After + public void closeContext() { + this.context.close(); + } + + @Test + public void disabledByDefault() { + load(); + assertFalse(this.context.containsBean("foo")); + } + + @Test + public void disabledExplicitly() { + load("spring.resources.chain.enabled:false"); + assertFalse(this.context.containsBean("foo")); + } + + @Test + public void enabledViaMainEnabledFlag() { + load("spring.resources.chain.enabled:true"); + assertTrue(this.context.containsBean("foo")); + } + + @Test + public void enabledViaFixedStrategyFlag() { + load("spring.resources.chain.strategy.fixed.enabled:true"); + assertTrue(this.context.containsBean("foo")); + } + + @Test + public void enabledViaContentStrategyFlag() { + load("spring.resources.chain.strategy.content.enabled:true"); + assertTrue(this.context.containsBean("foo")); + } + + + private void load(String... environment) { + this.context.register(Config.class); + EnvironmentTestUtils.addEnvironment(this.context, environment); + this.context.refresh(); + } + + @Configuration + static class Config { + + @Bean + @ConditionalOnEnabledResourceChain + public String foo() { + return "foo"; + } + + } + +}