24.7.3 Properties conversion
将外部应用配置绑定到@ConfigurationProperties
beans时,Spring会尝试将属性强制转换为正确的类型。如果需要自定义类型转换器,你可以提供一个ConversionService
bean(bean id为conversionService),或自定义属性编辑器(通过CustomEditorConfigurer
bean),或自定义Converters(bean定义时需要注解@ConfigurationPropertiesBinding
)。
由于该bean在应用程序生命周期的早期就需要使用,所以确保限制你的
ConversionService
使用的依赖。通常,在创建时期任何你需要的依赖可能都没完全初始化。比较建议使用@ConfigurationPropertiesBinding
方式
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.bind.ConverterBindingTests.TestConfig;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.ConfigurationPropertiesBinding;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.test.IntegrationTest;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.core.convert.converter.Converter;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(TestConfig.class)
@IntegrationTest("foo=bar")
public class ConverterBindingTests {
@Value("${foo:}")
private String foo;
@Autowired
private Wrapper properties;
@Test
public void overridingOfPropertiesOrderOfAtPropertySources() {
assertThat(this.properties.getFoo().getName(), is(this.foo));
}
@Configuration
@EnableConfigurationProperties(Wrapper.class)
public static class TestConfig {
@Bean
@ConfigurationPropertiesBinding
public Converter<String, Foo> converter() {
return new Converter<String, ConverterBindingTests.Foo>() {
@Override
public Foo convert(String source) {
Foo foo = new Foo();
foo.setName(source);
return foo;
}
};
}
@Bean
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
}
public static class Foo {
private String name;
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
}
@ConfigurationProperties
public static class Wrapper {
private Foo foo;
public Foo getFoo() {
return this.foo;
}
public void setFoo(Foo foo) {
this.foo = foo;
}
}
}