From bd79ec2362770b99ba3a9d19b2ac97105b63d4b5 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Wed, 1 May 2013 14:01:13 +0100 Subject: [PATCH] [bs-22] Move @ConfigurationProperties processing to main jar Also add unit tests. Note also the start.groovy for the service sample now works. [#48127729] --- .../IntegrationBootstrapApplication.java | 2 +- .../service/ServiceBootstrapApplication.java | 4 +- .../sample/service/ServiceProperties.java | 4 +- .../start.groovy | 8 +- .../service/SecurityConfiguration.java | 2 +- .../service/ServiceAutoConfiguration.java | 2 +- .../service/TraceConfiguration.java | 3 +- ...urationPropertiesBindingConfiguration.java | 3 +- .../EnableConfigurationProperties.java | 6 +- ...ConfigurationPropertiesImportSelector.java | 11 +- .../EnableConfigurationPropertiesTests.java | 129 ++++++++++++++++++ 11 files changed, 151 insertions(+), 23 deletions(-) rename {spring-bootstrap-service/src/main/java/org/springframework/bootstrap/service => spring-bootstrap/src/main/java/org/springframework/bootstrap/context}/annotation/ConfigurationPropertiesBindingConfiguration.java (97%) rename {spring-bootstrap-service/src/main/java/org/springframework/bootstrap/service => spring-bootstrap/src/main/java/org/springframework/bootstrap/context}/annotation/EnableConfigurationProperties.java (86%) rename spring-bootstrap-service/src/main/java/org/springframework/bootstrap/service/annotation/ConfigurationPropertiesImportSelector.java => spring-bootstrap/src/main/java/org/springframework/bootstrap/context/annotation/EnableConfigurationPropertiesImportSelector.java (90%) create mode 100644 spring-bootstrap/src/test/java/org/springframework/bootstrap/context/annotation/EnableConfigurationPropertiesTests.java diff --git a/spring-bootstrap-samples/spring-bootstrap-integration-sample/src/main/java/org/springframework/bootstrap/sample/consumer/IntegrationBootstrapApplication.java b/spring-bootstrap-samples/spring-bootstrap-integration-sample/src/main/java/org/springframework/bootstrap/sample/consumer/IntegrationBootstrapApplication.java index dab26d66311..5da0cdfe3ad 100644 --- a/spring-bootstrap-samples/spring-bootstrap-integration-sample/src/main/java/org/springframework/bootstrap/sample/consumer/IntegrationBootstrapApplication.java +++ b/spring-bootstrap-samples/spring-bootstrap-integration-sample/src/main/java/org/springframework/bootstrap/sample/consumer/IntegrationBootstrapApplication.java @@ -2,7 +2,7 @@ package org.springframework.bootstrap.sample.consumer; import org.springframework.bootstrap.SpringApplication; import org.springframework.bootstrap.context.annotation.EnableAutoConfiguration; -import org.springframework.bootstrap.service.annotation.EnableConfigurationProperties; +import org.springframework.bootstrap.context.annotation.EnableConfigurationProperties; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.ImportResource; diff --git a/spring-bootstrap-samples/spring-bootstrap-service-sample/src/main/java/org/springframework/bootstrap/sample/service/ServiceBootstrapApplication.java b/spring-bootstrap-samples/spring-bootstrap-service-sample/src/main/java/org/springframework/bootstrap/sample/service/ServiceBootstrapApplication.java index 7e1b9c3dcbb..fcb34a72624 100644 --- a/spring-bootstrap-samples/spring-bootstrap-service-sample/src/main/java/org/springframework/bootstrap/sample/service/ServiceBootstrapApplication.java +++ b/spring-bootstrap-samples/spring-bootstrap-service-sample/src/main/java/org/springframework/bootstrap/sample/service/ServiceBootstrapApplication.java @@ -2,13 +2,13 @@ package org.springframework.bootstrap.sample.service; import org.springframework.bootstrap.SpringApplication; import org.springframework.bootstrap.context.annotation.EnableAutoConfiguration; -import org.springframework.bootstrap.service.annotation.EnableConfigurationProperties; +import org.springframework.bootstrap.context.annotation.EnableConfigurationProperties; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; @Configuration @EnableAutoConfiguration -@EnableConfigurationProperties(ServiceProperties.class) +@EnableConfigurationProperties @ComponentScan public class ServiceBootstrapApplication { diff --git a/spring-bootstrap-samples/spring-bootstrap-service-sample/src/main/java/org/springframework/bootstrap/sample/service/ServiceProperties.java b/spring-bootstrap-samples/spring-bootstrap-service-sample/src/main/java/org/springframework/bootstrap/sample/service/ServiceProperties.java index 47365436651..04b3009998f 100644 --- a/spring-bootstrap-samples/spring-bootstrap-service-sample/src/main/java/org/springframework/bootstrap/sample/service/ServiceProperties.java +++ b/spring-bootstrap-samples/spring-bootstrap-service-sample/src/main/java/org/springframework/bootstrap/sample/service/ServiceProperties.java @@ -16,14 +16,16 @@ package org.springframework.bootstrap.sample.service; import org.springframework.bootstrap.context.annotation.ConfigurationProperties; +import org.springframework.stereotype.Component; @ConfigurationProperties(name = "service", ignoreUnknownFields = false) +@Component public class ServiceProperties { private String name = "World"; public String getName() { - return name; + return this.name; } public void setName(String name) { diff --git a/spring-bootstrap-samples/spring-bootstrap-service-sample/start.groovy b/spring-bootstrap-samples/spring-bootstrap-service-sample/start.groovy index 53719fc6013..77d6d26b368 100644 --- a/spring-bootstrap-samples/spring-bootstrap-service-sample/start.groovy +++ b/spring-bootstrap-samples/spring-bootstrap-service-sample/start.groovy @@ -1,4 +1,4 @@ -@Configuration -@Import(org.springframework.bootstrap.sample.service.ServiceBootstrapApplication) -class Start { -} \ No newline at end of file +@Grab("org.springframework.bootstrap:spring-bootstrap-service:0.0.1-SNAPSHOT") +@Grab("org.springframework.bootstrap:spring-bootstrap-web-application:0.0.1-SNAPSHOT") +class Start { +} diff --git a/spring-bootstrap-service/src/main/java/org/springframework/bootstrap/autoconfigure/service/SecurityConfiguration.java b/spring-bootstrap-service/src/main/java/org/springframework/bootstrap/autoconfigure/service/SecurityConfiguration.java index f2346bf7453..47f6ebedf67 100644 --- a/spring-bootstrap-service/src/main/java/org/springframework/bootstrap/autoconfigure/service/SecurityConfiguration.java +++ b/spring-bootstrap-service/src/main/java/org/springframework/bootstrap/autoconfigure/service/SecurityConfiguration.java @@ -20,7 +20,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.bootstrap.context.annotation.ConditionalOnClass; import org.springframework.bootstrap.context.annotation.ConditionalOnMissingBean; -import org.springframework.bootstrap.service.annotation.EnableConfigurationProperties; +import org.springframework.bootstrap.context.annotation.EnableConfigurationProperties; import org.springframework.bootstrap.service.properties.SecurityProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/spring-bootstrap-service/src/main/java/org/springframework/bootstrap/autoconfigure/service/ServiceAutoConfiguration.java b/spring-bootstrap-service/src/main/java/org/springframework/bootstrap/autoconfigure/service/ServiceAutoConfiguration.java index 495348256ba..7b3b9223035 100644 --- a/spring-bootstrap-service/src/main/java/org/springframework/bootstrap/autoconfigure/service/ServiceAutoConfiguration.java +++ b/spring-bootstrap-service/src/main/java/org/springframework/bootstrap/autoconfigure/service/ServiceAutoConfiguration.java @@ -20,7 +20,7 @@ import java.util.List; import org.springframework.bootstrap.context.annotation.ConditionalOnMissingBean; import org.springframework.bootstrap.context.annotation.EnableAutoConfiguration; -import org.springframework.bootstrap.service.annotation.EnableConfigurationProperties; +import org.springframework.bootstrap.context.annotation.EnableConfigurationProperties; import org.springframework.bootstrap.service.properties.EndpointsProperties; import org.springframework.bootstrap.service.properties.ManagementServerProperties; import org.springframework.bootstrap.service.properties.ServerProperties; diff --git a/spring-bootstrap-service/src/main/java/org/springframework/bootstrap/autoconfigure/service/TraceConfiguration.java b/spring-bootstrap-service/src/main/java/org/springframework/bootstrap/autoconfigure/service/TraceConfiguration.java index b38275fd48c..82a3390ac1e 100644 --- a/spring-bootstrap-service/src/main/java/org/springframework/bootstrap/autoconfigure/service/TraceConfiguration.java +++ b/spring-bootstrap-service/src/main/java/org/springframework/bootstrap/autoconfigure/service/TraceConfiguration.java @@ -30,7 +30,6 @@ import org.springframework.bootstrap.service.trace.TraceEndpoint; import org.springframework.bootstrap.service.trace.TraceRepository; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.security.web.SecurityFilterChain; import org.springframework.web.servlet.DispatcherServlet; /** @@ -47,7 +46,6 @@ public class TraceConfiguration { private TraceRepository traceRepository; @Configuration - @ConditionalOnClass(SecurityFilterChain.class) public static class SecurityFilterPostProcessorConfiguration { @Autowired(required = false) @@ -63,6 +61,7 @@ public class TraceConfiguration { private boolean dumpRequests; @Bean + @ConditionalOnClass(name = "org.springframework.security.web.SecurityFilterChain") public SecurityFilterPostProcessor securityFilterPostProcessor( BeanFactory beanFactory) { SecurityFilterPostProcessor processor = new SecurityFilterPostProcessor( diff --git a/spring-bootstrap-service/src/main/java/org/springframework/bootstrap/service/annotation/ConfigurationPropertiesBindingConfiguration.java b/spring-bootstrap/src/main/java/org/springframework/bootstrap/context/annotation/ConfigurationPropertiesBindingConfiguration.java similarity index 97% rename from spring-bootstrap-service/src/main/java/org/springframework/bootstrap/service/annotation/ConfigurationPropertiesBindingConfiguration.java rename to spring-bootstrap/src/main/java/org/springframework/bootstrap/context/annotation/ConfigurationPropertiesBindingConfiguration.java index 4d87cc413c8..cd299095d12 100644 --- a/spring-bootstrap-service/src/main/java/org/springframework/bootstrap/service/annotation/ConfigurationPropertiesBindingConfiguration.java +++ b/spring-bootstrap/src/main/java/org/springframework/bootstrap/context/annotation/ConfigurationPropertiesBindingConfiguration.java @@ -14,14 +14,13 @@ * limitations under the License. */ -package org.springframework.bootstrap.service.annotation; +package org.springframework.bootstrap.context.annotation; import java.lang.reflect.Field; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.bootstrap.bind.PropertySourcesBindingPostProcessor; -import org.springframework.bootstrap.context.annotation.ConfigurationProperties; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/spring-bootstrap-service/src/main/java/org/springframework/bootstrap/service/annotation/EnableConfigurationProperties.java b/spring-bootstrap/src/main/java/org/springframework/bootstrap/context/annotation/EnableConfigurationProperties.java similarity index 86% rename from spring-bootstrap-service/src/main/java/org/springframework/bootstrap/service/annotation/EnableConfigurationProperties.java rename to spring-bootstrap/src/main/java/org/springframework/bootstrap/context/annotation/EnableConfigurationProperties.java index 64ddc4e16c0..f1b7bde9de5 100644 --- a/spring-bootstrap-service/src/main/java/org/springframework/bootstrap/service/annotation/EnableConfigurationProperties.java +++ b/spring-bootstrap/src/main/java/org/springframework/bootstrap/context/annotation/EnableConfigurationProperties.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.bootstrap.service.annotation; +package org.springframework.bootstrap.context.annotation; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; @@ -30,9 +30,9 @@ import org.springframework.context.annotation.Import; @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented -@Import(ConfigurationPropertiesImportSelector.class) +@Import(EnableConfigurationPropertiesImportSelector.class) public @interface EnableConfigurationProperties { - Class[] value() default { void.class }; + Class[] value() default {}; } diff --git a/spring-bootstrap-service/src/main/java/org/springframework/bootstrap/service/annotation/ConfigurationPropertiesImportSelector.java b/spring-bootstrap/src/main/java/org/springframework/bootstrap/context/annotation/EnableConfigurationPropertiesImportSelector.java similarity index 90% rename from spring-bootstrap-service/src/main/java/org/springframework/bootstrap/service/annotation/ConfigurationPropertiesImportSelector.java rename to spring-bootstrap/src/main/java/org/springframework/bootstrap/context/annotation/EnableConfigurationPropertiesImportSelector.java index fb32f7adc6a..8cc973c6416 100644 --- a/spring-bootstrap-service/src/main/java/org/springframework/bootstrap/service/annotation/ConfigurationPropertiesImportSelector.java +++ b/spring-bootstrap/src/main/java/org/springframework/bootstrap/context/annotation/EnableConfigurationPropertiesImportSelector.java @@ -14,14 +14,13 @@ * limitations under the License. */ -package org.springframework.bootstrap.service.annotation; +package org.springframework.bootstrap.context.annotation; import java.util.ArrayList; import java.util.List; import org.springframework.beans.factory.support.BeanDefinitionBuilder; import org.springframework.beans.factory.support.BeanDefinitionRegistry; -import org.springframework.bootstrap.context.annotation.ConfigurationProperties; import org.springframework.context.annotation.ImportBeanDefinitionRegistrar; import org.springframework.context.annotation.ImportSelector; import org.springframework.core.type.AnnotationMetadata; @@ -39,14 +38,14 @@ import org.springframework.util.MultiValueMap; * * @author Dave Syer */ -public class ConfigurationPropertiesImportSelector implements ImportSelector { +public class EnableConfigurationPropertiesImportSelector implements ImportSelector { @Override public String[] selectImports(AnnotationMetadata metadata) { MultiValueMap attributes = metadata.getAllAnnotationAttributes( EnableConfigurationProperties.class.getName(), false); - Object type = attributes.getFirst("value"); - if (type == void.class) { + Object[] type = (Object[]) attributes.getFirst("value"); + if (type == null || type.length == 0) { return new String[] { ConfigurationPropertiesBindingConfiguration.class .getName() }; } @@ -74,7 +73,7 @@ public class ConfigurationPropertiesImportSelector implements ImportSelector { ArrayList> result = new ArrayList>(); for (Object object : list) { for (Object value : (Object[]) object) { - if (value instanceof Class) { + if (value instanceof Class && value != void.class) { result.add((Class) value); } } diff --git a/spring-bootstrap/src/test/java/org/springframework/bootstrap/context/annotation/EnableConfigurationPropertiesTests.java b/spring-bootstrap/src/test/java/org/springframework/bootstrap/context/annotation/EnableConfigurationPropertiesTests.java new file mode 100644 index 00000000000..896a248dbc9 --- /dev/null +++ b/spring-bootstrap/src/test/java/org/springframework/bootstrap/context/annotation/EnableConfigurationPropertiesTests.java @@ -0,0 +1,129 @@ +/* + * Copyright 2012-2013 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.bootstrap.context.annotation; + +import java.util.Properties; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.env.PropertiesPropertySource; +import org.springframework.core.io.ByteArrayResource; +import org.springframework.core.io.support.PropertiesLoaderUtils; + +import static org.junit.Assert.assertEquals; + +/** + * @author Dave Syer + * + */ +public class EnableConfigurationPropertiesTests { + + private AnnotationConfigApplicationContext context; + + @Before + public void open() throws Exception { + this.context = new AnnotationConfigApplicationContext(); + this.context + .getEnvironment() + .getPropertySources() + .addFirst( + new PropertiesPropertySource("props", + getProperties("external.name=foo\nanother.name=bar"))); + } + + @After + public void close() { + if (this.context != null) { + this.context.close(); + } + } + + @Test + public void testSimpleAutoConfig() throws Exception { + this.context.register(ExampleConfig.class); + this.context.refresh(); + assertEquals("foo", this.context.getBean(External.class).getName()); + } + + @Test + public void testExplicitType() throws Exception { + this.context.register(AnotherExampleConfig.class); + this.context.refresh(); + assertEquals("foo", this.context.getBean(External.class).getName()); + } + + @Test + public void testMultipleExplicitTypes() throws Exception { + this.context.register(FurtherExampleConfig.class); + this.context.refresh(); + assertEquals("foo", this.context.getBean(External.class).getName()); + assertEquals("bar", this.context.getBean(Another.class).getName()); + } + + private Properties getProperties(String values) throws Exception { + return PropertiesLoaderUtils.loadProperties(new ByteArrayResource(values + .getBytes())); + } + + @EnableConfigurationProperties + @Configuration + public static class ExampleConfig { + @Bean + public External external() { + return new External(); + } + } + + @EnableConfigurationProperties(External.class) + @Configuration + public static class AnotherExampleConfig { + } + + @EnableConfigurationProperties({ External.class, Another.class }) + @Configuration + public static class FurtherExampleConfig { + } + + @ConfigurationProperties(name = "external") + public static class External { + private String name; + + public String getName() { + return this.name; + } + + public void setName(String name) { + this.name = name; + } + } + + @ConfigurationProperties(name = "another") + public static class Another { + private String name; + + public String getName() { + return this.name; + } + + public void setName(String name) { + this.name = name; + } + } +}