diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/properties/ConfigurationPropertiesBinder.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/properties/ConfigurationPropertiesBinder.java index 452726be3c3..1575e5c9ea0 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/properties/ConfigurationPropertiesBinder.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/properties/ConfigurationPropertiesBinder.java @@ -55,7 +55,9 @@ class ConfigurationPropertiesBinder { private final Validator configurationPropertiesValidator; - private final Validator jsr303Validator; + private final boolean jsr303Present; + + private volatile Validator jsr303Validator; private volatile Binder binder; @@ -66,8 +68,8 @@ class ConfigurationPropertiesBinder { .getPropertySources(); this.configurationPropertiesValidator = getConfigurationPropertiesValidator( applicationContext, validatorBeanName); - this.jsr303Validator = ConfigurationPropertiesJsr303Validator - .getIfJsr303Present(applicationContext); + this.jsr303Present = ConfigurationPropertiesJsr303Validator + .isJsr303Present(applicationContext); } public void bind(Bindable target) { @@ -93,9 +95,8 @@ class ConfigurationPropertiesBinder { if (this.configurationPropertiesValidator != null) { validators.add(this.configurationPropertiesValidator); } - if (this.jsr303Validator != null - && target.getAnnotation(Validated.class) != null) { - validators.add(this.jsr303Validator); + if (this.jsr303Present && target.getAnnotation(Validated.class) != null) { + validators.add(getJsr303Validator()); } if (target.getValue() != null && target.getValue().get() instanceof Validator) { validators.add((Validator) target.getValue().get()); @@ -103,6 +104,14 @@ class ConfigurationPropertiesBinder { return validators; } + private Validator getJsr303Validator() { + if (this.jsr303Validator == null) { + this.jsr303Validator = new ConfigurationPropertiesJsr303Validator( + this.applicationContext); + } + return this.jsr303Validator; + } + private BindHandler getBindHandler(ConfigurationProperties annotation, List validators) { BindHandler handler = new IgnoreTopLevelConverterNotFoundBindHandler(); diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/properties/ConfigurationPropertiesJsr303Validator.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/properties/ConfigurationPropertiesJsr303Validator.java index 3c8cf0bfdfe..bf70742cfec 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/properties/ConfigurationPropertiesJsr303Validator.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/properties/ConfigurationPropertiesJsr303Validator.java @@ -38,8 +38,7 @@ final class ConfigurationPropertiesJsr303Validator implements Validator { private final Delegate delegate; - private ConfigurationPropertiesJsr303Validator( - ApplicationContext applicationContext) { + ConfigurationPropertiesJsr303Validator(ApplicationContext applicationContext) { this.delegate = new Delegate(applicationContext); } @@ -53,15 +52,14 @@ final class ConfigurationPropertiesJsr303Validator implements Validator { this.delegate.validate(target, errors); } - public static ConfigurationPropertiesJsr303Validator getIfJsr303Present( - ApplicationContext applicationContext) { + public static boolean isJsr303Present(ApplicationContext applicationContext) { ClassLoader classLoader = applicationContext.getClassLoader(); for (String validatorClass : VALIDATOR_CLASSES) { if (!ClassUtils.isPresent(validatorClass, classLoader)) { - return null; + return false; } } - return new ConfigurationPropertiesJsr303Validator(applicationContext); + return true; } private static class Delegate extends LocalValidatorFactoryBean { diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/diagnostics/analyzer/ValidationExceptionFailureAnalyzerTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/diagnostics/analyzer/ValidationExceptionFailureAnalyzerTests.java index d5c50d82e41..bcd19182478 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/diagnostics/analyzer/ValidationExceptionFailureAnalyzerTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/diagnostics/analyzer/ValidationExceptionFailureAnalyzerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2017 the original author or authors. + * Copyright 2012-2018 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. @@ -25,6 +25,7 @@ import org.springframework.boot.diagnostics.FailureAnalysis; import org.springframework.boot.testsupport.runner.classpath.ClassPathExclusions; import org.springframework.boot.testsupport.runner.classpath.ModifiedClassPathRunner; import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.springframework.validation.annotation.Validated; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.Assert.fail; @@ -39,7 +40,7 @@ import static org.junit.Assert.fail; public class ValidationExceptionFailureAnalyzerTests { @Test - public void test() { + public void validatedPropertiesTest() { try { new AnnotationConfigApplicationContext(TestConfiguration.class).close(); fail("Expected failure did not occur"); @@ -51,6 +52,12 @@ public class ValidationExceptionFailureAnalyzerTests { } } + @Test + public void nonValidatedPropertiesTest() { + new AnnotationConfigApplicationContext(NonValidatedTestConfiguration.class) + .close(); + } + @EnableConfigurationProperties(TestProperties.class) static class TestConfiguration { @@ -60,8 +67,22 @@ public class ValidationExceptionFailureAnalyzerTests { } @ConfigurationProperties("test") + @Validated private static class TestProperties { } + @EnableConfigurationProperties(NonValidatedTestProperties.class) + static class NonValidatedTestConfiguration { + + NonValidatedTestConfiguration(NonValidatedTestProperties testProperties) { + } + + } + + @ConfigurationProperties("test") + private static class NonValidatedTestProperties { + + } + }