diff --git a/spring-boot/src/main/java/org/springframework/boot/context/properties/ConfigurationPropertiesBindingPostProcessor.java b/spring-boot/src/main/java/org/springframework/boot/context/properties/ConfigurationPropertiesBindingPostProcessor.java index 9797d8dc4f..ca59446eb5 100644 --- a/spring-boot/src/main/java/org/springframework/boot/context/properties/ConfigurationPropertiesBindingPostProcessor.java +++ b/spring-boot/src/main/java/org/springframework/boot/context/properties/ConfigurationPropertiesBindingPostProcessor.java @@ -291,18 +291,21 @@ public class ConfigurationPropertiesBindingPostProcessor implements BeanPostProc @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { - ConfigurationProperties annotation = AnnotationUtils - .findAnnotation(bean.getClass(), ConfigurationProperties.class); - Object bound = bean; + ConfigurationProperties annotation = getAnnotation(bean, beanName); if (annotation != null) { - bound = postProcessBeforeInitialization(bean, beanName, annotation); + postProcessBeforeInitialization(bean, beanName, annotation); } - annotation = this.beans.findFactoryAnnotation(beanName, + return bean; + } + + private ConfigurationProperties getAnnotation(Object bean, String beanName) { + ConfigurationProperties annotation = this.beans.findFactoryAnnotation(beanName, ConfigurationProperties.class); - if (annotation != null) { - bound = postProcessBeforeInitialization(bean, beanName, annotation); + if (annotation == null) { + annotation = AnnotationUtils.findAnnotation(bean.getClass(), + ConfigurationProperties.class); } - return bound; + return annotation; } @Override @@ -311,7 +314,7 @@ public class ConfigurationPropertiesBindingPostProcessor implements BeanPostProc return bean; } - private Object postProcessBeforeInitialization(Object bean, String beanName, + private void postProcessBeforeInitialization(Object bean, String beanName, ConfigurationProperties annotation) { Binder binder = getBinder(); Validator validator = determineValidator(bean); @@ -319,7 +322,6 @@ public class ConfigurationPropertiesBindingPostProcessor implements BeanPostProc Bindable bindable = Bindable.ofInstance(bean); try { binder.bind(annotation.prefix(), bindable, handler); - return bean; } catch (Exception ex) { String targetClass = ClassUtils.getShortName(bean.getClass()); diff --git a/spring-boot/src/main/java/org/springframework/boot/context/properties/bind/Binder.java b/spring-boot/src/main/java/org/springframework/boot/context/properties/bind/Binder.java index f8c11a9bc7..d5ad6b28b4 100644 --- a/spring-boot/src/main/java/org/springframework/boot/context/properties/bind/Binder.java +++ b/spring-boot/src/main/java/org/springframework/boot/context/properties/bind/Binder.java @@ -235,11 +235,14 @@ public class Binder { private Object bindObject(ConfigurationPropertyName name, Bindable target, BindHandler handler, Context context) throws Exception { + ConfigurationProperty property = findProperty(name, context); + if (property == null && containsNoDescendantOf(context.streamSources(), name)) { + return null; + } AggregateBinder aggregateBinder = getAggregateBinder(target, context); if (aggregateBinder != null) { return bindAggregate(name, target, handler, context, aggregateBinder); } - ConfigurationProperty property = findProperty(name, context); if (property != null) { return bindProperty(name, target, handler, context, property); } diff --git a/spring-boot/src/main/java/org/springframework/boot/context/properties/source/ConfigurationPropertySources.java b/spring-boot/src/main/java/org/springframework/boot/context/properties/source/ConfigurationPropertySources.java index 1ca9f163e5..0bcddbb5ac 100644 --- a/spring-boot/src/main/java/org/springframework/boot/context/properties/source/ConfigurationPropertySources.java +++ b/spring-boot/src/main/java/org/springframework/boot/context/properties/source/ConfigurationPropertySources.java @@ -21,7 +21,6 @@ import java.util.Map; import java.util.Optional; import java.util.WeakHashMap; import java.util.function.Function; -import java.util.stream.Collectors; import java.util.stream.Stream; import java.util.stream.StreamSupport; @@ -74,7 +73,7 @@ public class ConfigurationPropertySources public Iterator iterator() { return streamPropertySources(this.propertySources) .filter(s -> !(s instanceof ConfigurationPropertySourcesPropertySource)) - .map(this::adapt).collect(Collectors.toList()).iterator(); + .map(this::adapt).iterator(); } private Stream> streamPropertySources(PropertySources sources) { diff --git a/spring-boot/src/main/java/org/springframework/boot/context/properties/source/DefaultPropertyMapper.java b/spring-boot/src/main/java/org/springframework/boot/context/properties/source/DefaultPropertyMapper.java index 34111a6ab9..5ef4443d12 100644 --- a/spring-boot/src/main/java/org/springframework/boot/context/properties/source/DefaultPropertyMapper.java +++ b/spring-boot/src/main/java/org/springframework/boot/context/properties/source/DefaultPropertyMapper.java @@ -52,6 +52,7 @@ class DefaultPropertyMapper implements PropertyMapper { String convertedName = configurationPropertyName.toString(); mapping = Collections.singletonList( new PropertyMapping(convertedName, configurationPropertyName)); + this.configurationPropertySourceCache.put(configurationPropertyName, mapping); } return mapping; } diff --git a/spring-boot/src/main/java/org/springframework/boot/context/properties/source/FilteredIterableConfigurationPropertiesSource.java b/spring-boot/src/main/java/org/springframework/boot/context/properties/source/FilteredIterableConfigurationPropertiesSource.java index 133155381b..f7d5f0b37c 100644 --- a/spring-boot/src/main/java/org/springframework/boot/context/properties/source/FilteredIterableConfigurationPropertiesSource.java +++ b/spring-boot/src/main/java/org/springframework/boot/context/properties/source/FilteredIterableConfigurationPropertiesSource.java @@ -49,7 +49,7 @@ class FilteredIterableConfigurationPropertiesSource @Override public Optional containsDescendantOf(ConfigurationPropertyName name) { - return Optional.of(stream().filter(name::isAncestorOf).findFirst().isPresent()); + return Optional.of(stream().anyMatch(name::isAncestorOf)); } } diff --git a/spring-boot/src/main/java/org/springframework/boot/context/properties/source/IterableConfigurationPropertySource.java b/spring-boot/src/main/java/org/springframework/boot/context/properties/source/IterableConfigurationPropertySource.java index 3658524fe4..c82511376c 100644 --- a/spring-boot/src/main/java/org/springframework/boot/context/properties/source/IterableConfigurationPropertySource.java +++ b/spring-boot/src/main/java/org/springframework/boot/context/properties/source/IterableConfigurationPropertySource.java @@ -63,7 +63,7 @@ public interface IterableConfigurationPropertySource @Override default Optional containsDescendantOf(ConfigurationPropertyName name) { - return Optional.of(stream().filter(name::isAncestorOf).findFirst().isPresent()); + return Optional.of(stream().anyMatch(name::isAncestorOf)); } @Override diff --git a/spring-boot/src/main/java/org/springframework/boot/context/properties/source/PropertySourceIterableConfigurationPropertySource.java b/spring-boot/src/main/java/org/springframework/boot/context/properties/source/PropertySourceIterableConfigurationPropertySource.java index 72a81f35e7..f017b3457d 100644 --- a/spring-boot/src/main/java/org/springframework/boot/context/properties/source/PropertySourceIterableConfigurationPropertySource.java +++ b/spring-boot/src/main/java/org/springframework/boot/context/properties/source/PropertySourceIterableConfigurationPropertySource.java @@ -90,7 +90,7 @@ class PropertySourceIterableConfigurationPropertySource @Override public Optional containsDescendantOf(ConfigurationPropertyName name) { - return Optional.of(stream().filter(name::isAncestorOf).findFirst().isPresent()); + return Optional.of(stream().anyMatch(name::isAncestorOf)); } private List getConfigurationPropertyNames() {