From 61a94f212de001a323e7eb7de3a19709412752c9 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Thu, 2 May 2013 16:18:21 +0100 Subject: [PATCH] [bs-89] Allow user to plugin validator for @ConfigurationProperties * Also fix ordering problem in integration tests (An application context not being closed led to port 8080 being already in use.) * Validator can be specified by providing a Spring Validator with bean id configurationPropertiesValidator. [Fixes #49067859] --- .../service/ServerConfiguration.java | 8 ++--- .../annotation/AbstractOnBeanCondition.java | 2 +- ...urationPropertiesBindingConfiguration.java | 18 ++++++++-- .../bootstrap/AdhocTestSuite.java | 35 +++++++++++++++++++ .../bootstrap/main/SimpleMainTests.java | 2 ++ 5 files changed, 57 insertions(+), 8 deletions(-) create mode 100644 spring-bootstrap/src/test/java/org/springframework/bootstrap/AdhocTestSuite.java diff --git a/spring-bootstrap-service/src/main/java/org/springframework/bootstrap/autoconfigure/service/ServerConfiguration.java b/spring-bootstrap-service/src/main/java/org/springframework/bootstrap/autoconfigure/service/ServerConfiguration.java index 675ba5a55e1..a8524f1eda5 100644 --- a/spring-bootstrap-service/src/main/java/org/springframework/bootstrap/autoconfigure/service/ServerConfiguration.java +++ b/spring-bootstrap-service/src/main/java/org/springframework/bootstrap/autoconfigure/service/ServerConfiguration.java @@ -89,16 +89,16 @@ public class ServerConfiguration implements BeanPostProcessor, BeanFactoryAware && !this.initialized) { // Cannot use @Autowired because the injection happens too early - ServerProperties configuration = this.beanFactory + ServerProperties server = this.beanFactory .getBean(ServerProperties.class); AbstractEmbeddedServletContainerFactory factory = (AbstractEmbeddedServletContainerFactory) bean; - factory.setPort(configuration.getPort()); - factory.setContextPath(configuration.getContextPath()); + factory.setPort(server.getPort()); + factory.setContextPath(server.getContextPath()); if (factory instanceof TomcatEmbeddedServletContainerFactory) { configureTomcat((TomcatEmbeddedServletContainerFactory) factory, - configuration); + server); } factory.setErrorPages(Collections diff --git a/spring-bootstrap/src/main/java/org/springframework/bootstrap/context/annotation/AbstractOnBeanCondition.java b/spring-bootstrap/src/main/java/org/springframework/bootstrap/context/annotation/AbstractOnBeanCondition.java index 77e1d67ed30..b84b0bbf21a 100644 --- a/spring-bootstrap/src/main/java/org/springframework/bootstrap/context/annotation/AbstractOnBeanCondition.java +++ b/spring-bootstrap/src/main/java/org/springframework/bootstrap/context/annotation/AbstractOnBeanCondition.java @@ -41,7 +41,7 @@ abstract class AbstractOnBeanCondition implements Condition { MultiValueMap attributes = metadata.getAllAnnotationAttributes( annotationClass().getName(), true); List beanClasses = collect(attributes, "value"); - List beanNames = collect(attributes, "value"); + List beanNames = collect(attributes, "name"); Assert.isTrue(beanClasses.size() > 0 || beanNames.size() > 0, "@" + ClassUtils.getShortName(annotationClass()) + " annotations must specify at least one bean"); diff --git a/spring-bootstrap/src/main/java/org/springframework/bootstrap/context/annotation/ConfigurationPropertiesBindingConfiguration.java b/spring-bootstrap/src/main/java/org/springframework/bootstrap/context/annotation/ConfigurationPropertiesBindingConfiguration.java index 9b4942a8c0f..7d8058f3283 100644 --- a/spring-bootstrap/src/main/java/org/springframework/bootstrap/context/annotation/ConfigurationPropertiesBindingConfiguration.java +++ b/spring-bootstrap/src/main/java/org/springframework/bootstrap/context/annotation/ConfigurationPropertiesBindingConfiguration.java @@ -31,6 +31,7 @@ import org.springframework.core.env.MutablePropertySources; import org.springframework.core.env.PropertySource; import org.springframework.core.env.PropertySources; import org.springframework.util.ReflectionUtils; +import org.springframework.validation.Validator; import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean; /** @@ -42,6 +43,8 @@ import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean; @Configuration public class ConfigurationPropertiesBindingConfiguration { + public final static String VALIDATOR_BEAN_NAME = "configurationPropertiesValidator"; + @Autowired(required = false) private PropertySourcesPlaceholderConfigurer configurer; @@ -52,6 +55,17 @@ public class ConfigurationPropertiesBindingConfiguration { @Qualifier(ConfigurableApplicationContext.CONVERSION_SERVICE_BEAN_NAME) private ConversionService conversionService; + @Autowired(required = false) + @Qualifier(VALIDATOR_BEAN_NAME) + private Validator validator; + + @Bean + @ConditionalOnMissingBean(name = VALIDATOR_BEAN_NAME) + @ConditionalOnClass(name = "javax.validation.Validator") + protected Validator configurationPropertiesValidator() { + return new LocalValidatorFactoryBean(); + } + /** * Lifecycle hook that binds application properties to any bean whose type is * decorated with {@link ConfigurationProperties} annotation. @@ -74,9 +88,7 @@ public class ConfigurationPropertiesBindingConfiguration { } } PropertySourcesBindingPostProcessor processor = new PropertySourcesBindingPostProcessor(); - LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean(); - validator.afterPropertiesSet(); - processor.setValidator(validator); + processor.setValidator(this.validator); processor.setConversionService(this.conversionService); processor.setPropertySources(propertySources); return processor; diff --git a/spring-bootstrap/src/test/java/org/springframework/bootstrap/AdhocTestSuite.java b/spring-bootstrap/src/test/java/org/springframework/bootstrap/AdhocTestSuite.java new file mode 100644 index 00000000000..d726709ae71 --- /dev/null +++ b/spring-bootstrap/src/test/java/org/springframework/bootstrap/AdhocTestSuite.java @@ -0,0 +1,35 @@ +/* + * 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; + +import org.junit.Ignore; +import org.junit.runner.RunWith; +import org.junit.runners.Suite; +import org.junit.runners.Suite.SuiteClasses; +import org.springframework.bootstrap.context.embedded.jetty.JettyEmbeddedServletContainerFactoryTests; +import org.springframework.bootstrap.main.SimpleMainTests; + +/** + * A test suite for probing weird ordering problems in the tests. + * @author Dave Syer + * + */ +@RunWith(Suite.class) +@SuiteClasses({ SimpleMainTests.class, JettyEmbeddedServletContainerFactoryTests.class }) +@Ignore +public class AdhocTestSuite { + +} diff --git a/spring-bootstrap/src/test/java/org/springframework/bootstrap/main/SimpleMainTests.java b/spring-bootstrap/src/test/java/org/springframework/bootstrap/main/SimpleMainTests.java index 348021a7114..fe41750a776 100644 --- a/spring-bootstrap/src/test/java/org/springframework/bootstrap/main/SimpleMainTests.java +++ b/spring-bootstrap/src/test/java/org/springframework/bootstrap/main/SimpleMainTests.java @@ -56,6 +56,8 @@ public class SimpleMainTests { public void xmlContext() throws Exception { Spring.main(new String[] { Spring.class.getName(), "org/springframework/bootstrap/sample-beans.xml" }); + this.context = Spring.getApplicationContext(); + assertNotNull(this.context); } }