Polish ConfigurationPropertiesBinder
Remove unused code and polish implementation so that the binder is not created on each invocation.
This commit is contained in:
parent
df277fb1b8
commit
937a62e0b8
|
@ -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.
|
||||
|
@ -38,7 +38,6 @@ import org.springframework.validation.Validator;
|
|||
* {@link PropertySource}.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
* @see ConfigurationPropertiesBinderBuilder
|
||||
*/
|
||||
class ConfigurationPropertiesBinder {
|
||||
|
||||
|
@ -50,6 +49,8 @@ class ConfigurationPropertiesBinder {
|
|||
|
||||
private Iterable<ConfigurationPropertySource> configurationSources;
|
||||
|
||||
private final Binder binder;
|
||||
|
||||
ConfigurationPropertiesBinder(Iterable<PropertySource<?>> propertySources,
|
||||
ConversionService conversionService, Validator validator) {
|
||||
Assert.notNull(propertySources, "PropertySources must not be null");
|
||||
|
@ -57,6 +58,10 @@ class ConfigurationPropertiesBinder {
|
|||
this.conversionService = conversionService;
|
||||
this.validator = validator;
|
||||
this.configurationSources = ConfigurationPropertySources.from(propertySources);
|
||||
this.binder = new Binder(this.configurationSources,
|
||||
new PropertySourcesPlaceholdersResolver(this.propertySources),
|
||||
this.conversionService);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -67,14 +72,11 @@ class ConfigurationPropertiesBinder {
|
|||
* @throws ConfigurationPropertiesBindingException if the binding failed
|
||||
*/
|
||||
void bind(Object target, ConfigurationProperties annotation) {
|
||||
Binder binder = new Binder(this.configurationSources,
|
||||
new PropertySourcesPlaceholdersResolver(this.propertySources),
|
||||
this.conversionService);
|
||||
Validator validator = determineValidator(target);
|
||||
BindHandler handler = getBindHandler(annotation, validator);
|
||||
Bindable<?> bindable = Bindable.ofInstance(target);
|
||||
try {
|
||||
binder.bind(annotation.prefix(), bindable, handler);
|
||||
this.binder.bind(annotation.prefix(), bindable, handler);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
String message = "Could not bind properties to '"
|
||||
|
|
|
@ -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.
|
||||
|
@ -27,7 +27,6 @@ import org.springframework.core.convert.ConversionService;
|
|||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.core.convert.converter.GenericConverter;
|
||||
import org.springframework.core.convert.support.DefaultConversionService;
|
||||
import org.springframework.core.env.ConfigurableEnvironment;
|
||||
import org.springframework.core.env.PropertySource;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
@ -72,42 +71,10 @@ class ConfigurationPropertiesBinderBuilder {
|
|||
this.applicationContext = applicationContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify the {@link ConversionService} to use or {@code null} to use the default.
|
||||
* <p>
|
||||
* By default, use a {@link ConversionService} bean named
|
||||
* {@value #CONVERSION_SERVICE_BEAN_NAME} if any. Otherwise create a
|
||||
* {@link DefaultConversionService} with any {@link ConfigurationPropertiesBinding}
|
||||
* qualified {@link Converter} and {@link GenericConverter} beans found in the
|
||||
* context.
|
||||
* @param conversionService the conversion service to use or {@code null}
|
||||
* @return this instance
|
||||
*/
|
||||
ConfigurationPropertiesBinderBuilder withConversionService(
|
||||
ConversionService conversionService) {
|
||||
this.conversionService = conversionService;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify the {@link Validator} to use or {@code null} to use the default.
|
||||
* <p>
|
||||
* By default, use a {@link Validator} bean named {@value #VALIDATOR_BEAN_NAME} if
|
||||
* any. If not, create a JSR 303 Validator if the necessary libraries are available.
|
||||
* No validation occurs otherwise.
|
||||
* @param validator the validator to use or {@code null}
|
||||
* @return this instance
|
||||
*/
|
||||
ConfigurationPropertiesBinderBuilder withValidator(Validator validator) {
|
||||
this.validator = validator;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify the {@link PropertySource property sources} to use.
|
||||
* @param propertySources the configuration the binder should use
|
||||
* @return this instance
|
||||
* @see #withEnvironment(ConfigurableEnvironment)
|
||||
*/
|
||||
ConfigurationPropertiesBinderBuilder withPropertySources(
|
||||
Iterable<PropertySource<?>> propertySources) {
|
||||
|
@ -115,18 +82,6 @@ class ConfigurationPropertiesBinderBuilder {
|
|||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify the {@link ConfigurableEnvironment Environment} to use, use all available
|
||||
* {@link PropertySource}.
|
||||
* @param environment the environment to use
|
||||
* @return this instance
|
||||
* @see #withPropertySources(Iterable)
|
||||
*/
|
||||
ConfigurationPropertiesBinderBuilder withEnvironment(
|
||||
ConfigurableEnvironment environment) {
|
||||
return withPropertySources(environment.getPropertySources());
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a {@link ConfigurationPropertiesBinder} based on the state of the builder,
|
||||
* discovering the {@link ConversionService} and {@link Validator} if necessary.
|
||||
|
|
|
@ -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.
|
||||
|
@ -26,12 +26,10 @@ import org.springframework.boot.context.properties.bind.validation.BindValidatio
|
|||
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;
|
||||
import org.springframework.test.context.support.TestPropertySourceUtils;
|
||||
import org.springframework.test.util.ReflectionTestUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.validation.Errors;
|
||||
import org.springframework.validation.ValidationUtils;
|
||||
import org.springframework.validation.Validator;
|
||||
|
@ -54,28 +52,11 @@ public class ConfigurationPropertiesBinderBuilderTests {
|
|||
|
||||
private final MockEnvironment environment = new MockEnvironment();
|
||||
|
||||
@Test
|
||||
public void useCustomConversionService() {
|
||||
DefaultConversionService conversionService = new DefaultConversionService();
|
||||
conversionService.addConverter(new AddressConverter());
|
||||
TestPropertySourceUtils.addInlinedPropertiesToEnvironment(this.environment,
|
||||
"test.address=FooStreet 42");
|
||||
ConfigurationPropertiesBinder binder = this.builder
|
||||
.withEnvironment(this.environment)
|
||||
.withConversionService(conversionService).build();
|
||||
PropertyWithAddress target = new PropertyWithAddress();
|
||||
bind(binder, target);
|
||||
assertThat(target.getAddress()).isNotNull();
|
||||
assertThat(target.getAddress().streetName).isEqualTo("FooStreet");
|
||||
assertThat(target.getAddress().number).isEqualTo(42);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void detectDefaultConversionService() {
|
||||
this.applicationContext.registerSingleton("conversionService",
|
||||
DefaultConversionService.class);
|
||||
ConfigurationPropertiesBinder binder = this.builder
|
||||
.withEnvironment(this.environment).build();
|
||||
ConfigurationPropertiesBinder binder = builderWithSources().build();
|
||||
assertThat(ReflectionTestUtils.getField(binder, "conversionService"))
|
||||
.isSameAs(this.applicationContext.getBean("conversionService"));
|
||||
}
|
||||
|
@ -84,48 +65,42 @@ public class ConfigurationPropertiesBinderBuilderTests {
|
|||
public void bindToJavaTimeDuration() {
|
||||
TestPropertySourceUtils.addInlinedPropertiesToEnvironment(this.environment,
|
||||
"test.duration=PT1M");
|
||||
ConfigurationPropertiesBinder binder = this.builder
|
||||
.withEnvironment(this.environment).build();
|
||||
ConfigurationPropertiesBinder binder = builderWithSources().build();
|
||||
PropertyWithDuration target = new PropertyWithDuration();
|
||||
bind(binder, target);
|
||||
assertThat(target.getDuration().getSeconds()).isEqualTo(60);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void useCustomValidator() {
|
||||
LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean();
|
||||
ConfigurationPropertiesBinder binder = this.builder
|
||||
.withEnvironment(this.environment).withValidator(validator).build();
|
||||
assertThat(ReflectionTestUtils.getField(binder, "validator")).isSameAs(validator);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void detectDefaultValidator() {
|
||||
this.applicationContext.registerSingleton(ConfigurationPropertiesBindingPostProcessor.VALIDATOR_BEAN_NAME,
|
||||
this.applicationContext.registerSingleton(
|
||||
ConfigurationPropertiesBindingPostProcessor.VALIDATOR_BEAN_NAME,
|
||||
LocalValidatorFactoryBean.class);
|
||||
ConfigurationPropertiesBinder binder = this.builder
|
||||
.withEnvironment(this.environment).build();
|
||||
assertThat(ReflectionTestUtils.getField(binder, "validator")).isSameAs(
|
||||
this.applicationContext.getBean(ConfigurationPropertiesBindingPostProcessor.VALIDATOR_BEAN_NAME));
|
||||
ConfigurationPropertiesBinder binder = builderWithSources().build();
|
||||
assertThat(ReflectionTestUtils.getField(binder, "validator"))
|
||||
.isSameAs(this.applicationContext.getBean(
|
||||
ConfigurationPropertiesBindingPostProcessor.VALIDATOR_BEAN_NAME));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validationWithoutJsr303() {
|
||||
ConfigurationPropertiesBinder binder = this.builder
|
||||
.withEnvironment(this.environment).build();
|
||||
ConfigurationPropertiesBinder binder = builderWithSources().build();
|
||||
assertThat(bindWithValidationErrors(binder, new PropertyWithoutJSR303())
|
||||
.getAllErrors()).hasSize(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validationWithJsr303() {
|
||||
ConfigurationPropertiesBinder binder = this.builder
|
||||
.withEnvironment(this.environment).build();
|
||||
ConfigurationPropertiesBinder binder = builderWithSources().build();
|
||||
assertThat(
|
||||
bindWithValidationErrors(binder, new PropertyWithJSR303()).getAllErrors())
|
||||
.hasSize(2);
|
||||
}
|
||||
|
||||
private ConfigurationPropertiesBinderBuilder builderWithSources() {
|
||||
return this.builder.withPropertySources(this.environment.getPropertySources());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validationWithJsr303AndValidInput() {
|
||||
TestPropertySourceUtils.addInlinedPropertiesToEnvironment(this.environment,
|
||||
|
@ -156,42 +131,6 @@ public class ConfigurationPropertiesBinderBuilderTests {
|
|||
ConfigurationProperties.class));
|
||||
}
|
||||
|
||||
@ConfigurationProperties(prefix = "test")
|
||||
public static class PropertyWithAddress {
|
||||
|
||||
private Address address;
|
||||
|
||||
public Address getAddress() {
|
||||
return this.address;
|
||||
}
|
||||
|
||||
public void setAddress(Address address) {
|
||||
this.address = address;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class Address {
|
||||
|
||||
private String streetName;
|
||||
|
||||
private Integer number;
|
||||
|
||||
Address(String streetName, Integer number) {
|
||||
this.streetName = streetName;
|
||||
this.number = number;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class AddressConverter implements Converter<String, Address> {
|
||||
@Override
|
||||
public Address convert(String source) {
|
||||
String[] split = StringUtils.split(source, " ");
|
||||
return new Address(split[0], Integer.valueOf(split[1]));
|
||||
}
|
||||
}
|
||||
|
||||
@ConfigurationProperties(prefix = "test")
|
||||
public static class PropertyWithDuration {
|
||||
|
||||
|
|
Loading…
Reference in New Issue