Use non-reflective APIs to retrieve config prop binding converters

See gh-14657
This commit is contained in:
Dave Syer 2018-10-02 10:46:27 +01:00 committed by Andy Wilkinson
parent a0bbb98b51
commit 2094e54ef2
2 changed files with 35 additions and 22 deletions

View File

@ -30,10 +30,15 @@ import org.springframework.beans.factory.annotation.Qualifier;
* *
* @author Dave Syer * @author Dave Syer
*/ */
@Qualifier @Qualifier(ConfigurationPropertiesBinding.VALUE)
@Target({ ElementType.TYPE, ElementType.METHOD }) @Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
@Documented @Documented
public @interface ConfigurationPropertiesBinding { public @interface ConfigurationPropertiesBinding {
/**
* Concrete value for the <code>@Qualifier</code>.
*/
String VALUE = "org.springframework.boot.context.properties.ConfigurationPropertiesBinding";
} }

View File

@ -16,11 +16,13 @@
package org.springframework.boot.context.properties; package org.springframework.boot.context.properties;
import java.util.Collections; import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.beans.factory.NoSuchBeanDefinitionException; import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.BeanFactoryAnnotationUtils;
import org.springframework.boot.convert.ApplicationConversionService; import org.springframework.boot.convert.ApplicationConversionService;
import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContext;
import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.ConfigurableApplicationContext;
@ -49,37 +51,43 @@ class ConversionServiceDeducer {
ConversionService.class); ConversionService.class);
} }
catch (NoSuchBeanDefinitionException ex) { catch (NoSuchBeanDefinitionException ex) {
return this.applicationContext.getAutowireCapableBeanFactory() return new Factory(this.applicationContext.getAutowireCapableBeanFactory())
.createBean(Factory.class).create(); .create();
} }
} }
private static class Factory { private static class Factory {
private List<Converter<?, ?>> converters = Collections.emptyList(); /**
* A list of custom converters (in addition to the defaults) to use when
private List<GenericConverter> genericConverters = Collections.emptyList(); * converting properties for binding.
*/
@SuppressWarnings("rawtypes")
private List<Converter> converters;
/** /**
* A list of custom converters (in addition to the defaults) to use when * A list of custom converters (in addition to the defaults) to use when
* converting properties for binding. * converting properties for binding.
* @param converters the converters to set
*/ */
@Autowired(required = false) private List<GenericConverter> genericConverters;
@ConfigurationPropertiesBinding
public void setConverters(List<Converter<?, ?>> converters) { Factory(BeanFactory beanFactory) {
this.converters = converters; this.converters = beans(beanFactory, Converter.class,
ConfigurationPropertiesBinding.VALUE);
this.genericConverters = beans(beanFactory, GenericConverter.class,
ConfigurationPropertiesBinding.VALUE);
} }
/** private static <T> List<T> beans(BeanFactory beanFactory, Class<T> type,
* A list of custom converters (in addition to the defaults) to use when String qualifier) {
* converting properties for binding. List<T> list = new ArrayList<>();
* @param converters the converters to set if (!(beanFactory instanceof ListableBeanFactory)) {
*/ return list;
@Autowired(required = false) }
@ConfigurationPropertiesBinding ListableBeanFactory listable = (ListableBeanFactory) beanFactory;
public void setGenericConverters(List<GenericConverter> converters) { list.addAll(BeanFactoryAnnotationUtils
this.genericConverters = converters; .qualifiedBeansOfType(listable, type, qualifier).values());
return list;
} }
public ConversionService create() { public ConversionService create() {