Make binder API private again

Closes gh-10867
This commit is contained in:
Stephane Nicoll 2017-11-17 11:23:34 +01:00
parent 0f69a157ac
commit 4ff8126217
6 changed files with 48 additions and 67 deletions

View File

@ -26,7 +26,6 @@ import org.springframework.boot.context.properties.bind.validation.ValidationBin
import org.springframework.boot.context.properties.source.ConfigurationPropertySource;
import org.springframework.boot.context.properties.source.ConfigurationPropertySources;
import org.springframework.boot.context.properties.source.UnboundElementsSourceFilter;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.env.PropertySource;
import org.springframework.util.Assert;
@ -39,10 +38,9 @@ import org.springframework.validation.Validator;
* {@link PropertySource}.
*
* @author Stephane Nicoll
* @since 2.0.0
* @see ConfigurationPropertiesBinderBuilder
*/
public class ConfigurationPropertiesBinder {
class ConfigurationPropertiesBinder {
private final Iterable<PropertySource<?>> propertySources;
@ -61,20 +59,6 @@ public class ConfigurationPropertiesBinder {
this.configurationSources = ConfigurationPropertySources.from(propertySources);
}
/**
* Bind the specified {@code target} object if it is annotated with
* {@link ConfigurationProperties}, otherwise ignore it.
* @param target the target to bind the configuration property sources to
* @throws ConfigurationPropertiesBindingException if the binding failed
*/
public void bind(Object target) {
ConfigurationProperties annotation = AnnotationUtils
.findAnnotation(target.getClass(), ConfigurationProperties.class);
if (annotation != null) {
bind(target, annotation);
}
}
/**
* Bind the specified {@code target} object using the configuration defined by the
* specified {@code annotation}.
@ -93,8 +77,10 @@ public class ConfigurationPropertiesBinder {
binder.bind(annotation.prefix(), bindable, handler);
}
catch (Exception ex) {
throw new ConfigurationPropertiesBindingException(target.getClass(),
getAnnotationDetails(annotation), ex);
String message = "Could not bind properties to '"
+ ClassUtils.getShortName(target.getClass()) + "': "
+ getAnnotationDetails(annotation);
throw new ConfigurationPropertiesBindingException(message, ex);
}
}

View File

@ -38,19 +38,18 @@ import org.springframework.validation.Validator;
* {@link ApplicationContext}.
*
* @author Stephane Nicoll
* @since 2.0.0
*/
public class ConfigurationPropertiesBinderBuilder {
class ConfigurationPropertiesBinderBuilder {
/**
* The bean name of the configuration properties validator.
*/
public static final String VALIDATOR_BEAN_NAME = "configurationPropertiesValidator";
private static final String VALIDATOR_BEAN_NAME = ConfigurationPropertiesBindingPostProcessor.VALIDATOR_BEAN_NAME;
/**
* The bean name of the configuration properties conversion service.
*/
public static final String CONVERSION_SERVICE_BEAN_NAME = ConfigurableApplicationContext.CONVERSION_SERVICE_BEAN_NAME;
private static final String CONVERSION_SERVICE_BEAN_NAME = ConfigurableApplicationContext.CONVERSION_SERVICE_BEAN_NAME;
private static final String[] VALIDATOR_CLASSES = { "javax.validation.Validator",
"javax.validation.ValidatorFactory",
@ -68,7 +67,7 @@ public class ConfigurationPropertiesBinderBuilder {
* Creates an instance with the {@link ApplicationContext} to use.
* @param applicationContext the application context
*/
public ConfigurationPropertiesBinderBuilder(ApplicationContext applicationContext) {
ConfigurationPropertiesBinderBuilder(ApplicationContext applicationContext) {
Assert.notNull(applicationContext, "ApplicationContext must not be null");
this.applicationContext = applicationContext;
}

View File

@ -17,32 +17,18 @@
package org.springframework.boot.context.properties;
import org.springframework.core.NestedExceptionUtils;
import org.springframework.util.ClassUtils;
/**
* Exception thrown when a {@code @ConfigurationProperties} annotated object failed to be
* bound.
*
* @author Stephane Nicoll
* @since 2.0.0
*/
public class ConfigurationPropertiesBindingException extends RuntimeException {
class ConfigurationPropertiesBindingException extends RuntimeException {
private final Class<?> targetClass;
public ConfigurationPropertiesBindingException(Class<?> targetClass, String message,
ConfigurationPropertiesBindingException(String message,
Throwable cause) {
super("Could not bind properties to '" + ClassUtils.getShortName(targetClass)
+ "': " + message, cause);
this.targetClass = targetClass;
}
/**
* Return the target type of the object that failed to be bound.
* @return the target {@link Class}
*/
public Class<?> getTargetClass() {
return this.targetClass;
super(message, cause);
}
/**

View File

@ -55,6 +55,11 @@ public class ConfigurationPropertiesBindingPostProcessor
implements BeanPostProcessor, BeanFactoryAware, EnvironmentAware,
ApplicationContextAware, InitializingBean, PriorityOrdered {
/**
* The bean name of the configuration properties validator.
*/
public static final String VALIDATOR_BEAN_NAME = "configurationPropertiesValidator";
private static final Log logger = LogFactory
.getLog(ConfigurationPropertiesBindingPostProcessor.class);

View File

@ -25,6 +25,7 @@ import org.junit.Test;
import org.springframework.boot.context.properties.bind.validation.BindValidationException;
import org.springframework.boot.context.properties.bind.validation.ValidationErrors;
import org.springframework.context.support.StaticApplicationContext;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.convert.converter.Converter;
import org.springframework.core.convert.support.DefaultConversionService;
import org.springframework.mock.env.MockEnvironment;
@ -63,7 +64,7 @@ public class ConfigurationPropertiesBinderBuilderTests {
.withEnvironment(this.environment)
.withConversionService(conversionService).build();
PropertyWithAddress target = new PropertyWithAddress();
binder.bind(target);
bind(binder, target);
assertThat(target.getAddress()).isNotNull();
assertThat(target.getAddress().streetName).isEqualTo("FooStreet");
assertThat(target.getAddress().number).isEqualTo(42);
@ -86,7 +87,7 @@ public class ConfigurationPropertiesBinderBuilderTests {
ConfigurationPropertiesBinder binder = this.builder
.withEnvironment(this.environment).build();
PropertyWithDuration target = new PropertyWithDuration();
binder.bind(target);
bind(binder, target);
assertThat(target.getDuration().getSeconds()).isEqualTo(60);
}
@ -122,7 +123,7 @@ public class ConfigurationPropertiesBinderBuilderTests {
.withEnvironment(this.environment).build();
assertThat(
bindWithValidationErrors(binder, new PropertyWithJSR303()).getAllErrors())
.hasSize(2);
.hasSize(2);
}
@Test
@ -132,7 +133,7 @@ public class ConfigurationPropertiesBinderBuilderTests {
ConfigurationPropertiesBinder binder = new ConfigurationPropertiesBinder(
this.environment.getPropertySources(), null, null);
PropertyWithJSR303 target = new PropertyWithJSR303();
binder.bind(target);
bind(binder, target);
assertThat(target.getFoo()).isEqualTo("123456");
assertThat(target.getBar()).isEqualTo("654321");
}
@ -140,7 +141,7 @@ public class ConfigurationPropertiesBinderBuilderTests {
private ValidationErrors bindWithValidationErrors(
ConfigurationPropertiesBinder binder, Object target) {
try {
binder.bind(target);
bind(binder, target);
throw new AssertionError("Should have failed to bind " + target);
}
catch (ConfigurationPropertiesBindingException ex) {
@ -150,6 +151,11 @@ public class ConfigurationPropertiesBinderBuilderTests {
}
}
private void bind(ConfigurationPropertiesBinder binder, Object target) {
binder.bind(target, AnnotationUtils
.findAnnotation(target.getClass(), ConfigurationProperties.class));
}
@ConfigurationProperties(prefix = "test")
public static class PropertyWithAddress {

View File

@ -25,6 +25,7 @@ import org.junit.Test;
import org.springframework.boot.context.properties.bind.BindException;
import org.springframework.boot.context.properties.bind.validation.BindValidationException;
import org.springframework.boot.context.properties.bind.validation.ValidationErrors;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.env.MapPropertySource;
import org.springframework.core.env.MutablePropertySources;
import org.springframework.core.env.StandardEnvironment;
@ -61,7 +62,7 @@ public class ConfigurationPropertiesBinderTests {
ConfigurationPropertiesBinder binder = new ConfigurationPropertiesBinder(
this.environment.getPropertySources(), null, null);
PersonProperties target = new PersonProperties();
binder.bind(target);
bind(binder, target);
assertThat(target.name).isEqualTo("John Smith");
assertThat(target.age).isEqualTo(42);
}
@ -74,7 +75,7 @@ public class ConfigurationPropertiesBinderTests {
this.environment.getPropertySources(), null, null);
PersonProperties target = new PersonProperties();
try {
binder.bind(target);
bind(binder, target);
fail("Expected exception");
}
catch (ConfigurationPropertiesBindingException ex) {
@ -92,17 +93,10 @@ public class ConfigurationPropertiesBinderTests {
ConfigurationPropertiesBinder binder = new ConfigurationPropertiesBinder(
this.environment.getPropertySources(), null, null);
PropertyWithIgnoreInvalidFields target = new PropertyWithIgnoreInvalidFields();
binder.bind(target);
bind(binder, target);
assertThat(target.getBar()).isEqualTo(0);
}
@Test
public void bindNonAnnotatedObject() {
ConfigurationPropertiesBinder binder = new ConfigurationPropertiesBinder(
this.environment.getPropertySources(), null, null);
binder.bind("FooBar");
}
@Test
public void bindToEnum() {
bindToEnum("test.theValue=foo");
@ -120,7 +114,7 @@ public class ConfigurationPropertiesBinderTests {
ConfigurationPropertiesBinder binder = new ConfigurationPropertiesBinder(
this.environment.getPropertySources(), null, null);
PropertyWithEnum target = new PropertyWithEnum();
binder.bind(target);
bind(binder, target);
assertThat(target.getTheValue()).isEqualTo(FooEnum.FOO);
}
@ -136,7 +130,7 @@ public class ConfigurationPropertiesBinderTests {
ConfigurationPropertiesBinder binder = new ConfigurationPropertiesBinder(
this.environment.getPropertySources(), null, null);
PropertyWithEnum target = new PropertyWithEnum();
binder.bind(target);
bind(binder, target);
assertThat(target.getTheValues()).contains(expected);
}
@ -147,7 +141,7 @@ public class ConfigurationPropertiesBinderTests {
ConfigurationPropertiesBinder binder = new ConfigurationPropertiesBinder(
this.environment.getPropertySources(), null, null);
PropertyWithCharArray target = new PropertyWithCharArray();
binder.bind(target);
bind(binder, target);
assertThat(target.getChars()).isEqualTo("word".toCharArray());
}
@ -163,7 +157,7 @@ public class ConfigurationPropertiesBinderTests {
ConfigurationPropertiesBinder binder = new ConfigurationPropertiesBinder(
this.environment.getPropertySources(), null, null);
PropertyWithRelaxedNames target = new PropertyWithRelaxedNames();
binder.bind(target);
bind(binder, target);
assertThat(target.getFooBar()).isEqualTo("test2");
assertThat(target.getBarBAZ()).isEqualTo("testb");
}
@ -175,7 +169,7 @@ public class ConfigurationPropertiesBinderTests {
ConfigurationPropertiesBinder binder = new ConfigurationPropertiesBinder(
this.environment.getPropertySources(), null, null);
PropertyWithNestedValue target = new PropertyWithNestedValue();
binder.bind(target);
bind(binder, target);
assertThat(target.getNested().getValue()).isEqualTo("test1");
}
@ -186,7 +180,7 @@ public class ConfigurationPropertiesBinderTests {
ConfigurationPropertiesBinder binder = new ConfigurationPropertiesBinder(
this.environment.getPropertySources(), null, null);
PropertiesWithMap target = new PropertiesWithMap();
binder.bind(target);
bind(binder, target);
assertThat(target.getMap()).containsOnly(entry("foo", "bar"));
}
@ -199,7 +193,7 @@ public class ConfigurationPropertiesBinderTests {
ConfigurationPropertiesBinder binder = new ConfigurationPropertiesBinder(
propertySources, null, null);
PropertiesWithComplexMap target = new PropertiesWithComplexMap();
binder.bind(target);
bind(binder, target);
assertThat(target.getMap()).containsOnlyKeys("foo");
assertThat(target.getMap().get("foo")).containsOnly(entry("bar", "baz"));
}
@ -214,7 +208,7 @@ public class ConfigurationPropertiesBinderTests {
ConfigurationPropertiesBinder binder = new ConfigurationPropertiesBinder(
propertySources, null, null);
PersonProperties target = new PersonProperties();
binder.bind(target);
bind(binder, target);
assertThat(target.name).isEqualTo("Jane");
}
@ -226,7 +220,7 @@ public class ConfigurationPropertiesBinderTests {
this.environment.getPropertySources(), null, null);
PropertyWithValidatingSetter target = new PropertyWithValidatingSetter();
try {
binder.bind(target);
bind(binder, target);
fail("Expected exception");
}
catch (ConfigurationPropertiesBindingException ex) {
@ -255,7 +249,7 @@ public class ConfigurationPropertiesBinderTests {
ConfigurationPropertiesBinder binder = new ConfigurationPropertiesBinder(
this.environment.getPropertySources(), null, validator);
PropertyWithValidatingSetter target = new PropertyWithValidatingSetter();
binder.bind(target);
bind(binder, target);
assertThat(target.getFoo()).isEqualTo("bar");
verify(validator, times(0)).validate(eq(target), any(Errors.class));
}
@ -263,7 +257,7 @@ public class ConfigurationPropertiesBinderTests {
private ValidationErrors bindWithValidationErrors(
ConfigurationPropertiesBinder binder, Object target) {
try {
binder.bind(target);
bind(binder, target);
throw new AssertionError("Should have failed to bind " + target);
}
catch (ConfigurationPropertiesBindingException ex) {
@ -273,6 +267,11 @@ public class ConfigurationPropertiesBinderTests {
}
}
private void bind(ConfigurationPropertiesBinder binder, Object target) {
binder.bind(target, AnnotationUtils
.findAnnotation(target.getClass(), ConfigurationProperties.class));
}
@ConfigurationProperties(value = "person", ignoreUnknownFields = false)
static class PersonProperties {