@ -1,5 +1,5 @@
/ *
* Copyright 2012 - 202 2 the original author or authors .
* Copyright 2012 - 202 3 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 .
@ -50,6 +50,7 @@ import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.annotation.MergedAnnotations ;
import org.springframework.core.convert.ConversionService ;
import org.springframework.core.env.PropertySources ;
import org.springframework.util.Assert ;
import org.springframework.validation.Validator ;
import org.springframework.validation.annotation.Validated ;
@ -64,8 +65,6 @@ class ConfigurationPropertiesBinder {
private static final String BEAN_NAME = "org.springframework.boot.context.internalConfigurationPropertiesBinder" ;
private static final String FACTORY_BEAN_NAME = "org.springframework.boot.context.internalConfigurationPropertiesBinderFactory" ;
private static final String VALIDATOR_BEAN_NAME = EnableConfigurationProperties . VALIDATOR_BEAN_NAME ;
private final ApplicationContext applicationContext ;
@ -189,18 +188,9 @@ class ConfigurationPropertiesBinder {
}
static void register ( BeanDefinitionRegistry registry ) {
if ( ! registry . containsBeanDefinition ( FACTORY_BEAN_NAME ) ) {
BeanDefinition definition = BeanDefinitionBuilder
. rootBeanDefinition ( ConfigurationPropertiesBinder . Factory . class ) . getBeanDefinition ( ) ;
definition . setRole ( BeanDefinition . ROLE_INFRASTRUCTURE ) ;
registry . registerBeanDefinition ( ConfigurationPropertiesBinder . FACTORY_BEAN_NAME , definition ) ;
}
if ( ! registry . containsBeanDefinition ( BEAN_NAME ) ) {
BeanDefinition definition = BeanDefinitionBuilder
. rootBeanDefinition ( ConfigurationPropertiesBinder . class ,
( ) - > ( ( BeanFactory ) registry )
. getBean ( FACTORY_BEAN_NAME , ConfigurationPropertiesBinder . Factory . class ) . create ( ) )
. getBeanDefinition ( ) ;
. rootBeanDefinition ( ConfigurationPropertiesBinderFactory . class ) . getBeanDefinition ( ) ;
definition . setRole ( BeanDefinition . ROLE_INFRASTRUCTURE ) ;
registry . registerBeanDefinition ( ConfigurationPropertiesBinder . BEAN_NAME , definition ) ;
}
@ -211,44 +201,49 @@ class ConfigurationPropertiesBinder {
}
/ * *
* Factory bean used to create the { @link ConfigurationPropertiesBinder } . The bean
* needs to be { @link ApplicationContextAware } since we can ' t directly inject an
* { @link ApplicationContext } into the constructor without causing eager
* { @link FactoryBean } initialization .
* { @link BindHandler } to deal with
* { @link ConfigurationProperties @ConfigurationProperties } concerns .
* /
static class Factory implements ApplicationContextAware {
private static class ConfigurationPropertiesBindHandler extends AbstractBindHandler {
private ApplicationContext applicationContext ;
ConfigurationPropertiesBindHandler ( BindHandler handler ) {
super ( handler ) ;
}
@Override
public void setApplicationContext ( ApplicationContext applicationContext ) throws BeansException {
this . applicationContext = applicationContext ;
public < T > Bindable < T > onStart ( ConfigurationPropertyName name , Bindable < T > target , BindContext context ) {
return isConfigurationProperties ( target . getType ( ) . resolve ( ) )
? target . withBindRestrictions ( BindRestriction . NO_DIRECT_PROPERTY ) : target ;
}
ConfigurationPropertiesBinder create ( ) {
return new ConfigurationPropertiesBinder ( this . applicationContext ) ;
private boolean isConfigurationProperties ( Class < ? > target ) {
return target ! = null & & MergedAnnotations . from ( target ) . isPresent ( ConfigurationProperties . class ) ;
}
}
/ * *
* { @link BindHandler } to deal with
* { @link ConfigurationProperties @ConfigurationProperties } concerns .
* { @link FactoryBean } to create the { @link ConfigurationPropertiesBinder } .
* /
private static class ConfigurationPropertiesBindHandler extends AbstractBindHandler {
static class ConfigurationPropertiesBinderFactory
implements FactoryBean < ConfigurationPropertiesBinder > , ApplicationContextAware {
ConfigurationPropertiesBindHandler ( BindHandler handler ) {
super ( handler ) ;
private ConfigurationPropertiesBinder binder ;
@Override
public void setApplicationContext ( ApplicationContext applicationContext ) throws BeansException {
this . binder = ( this . binder ! = null ) ? this . binder : new ConfigurationPropertiesBinder ( applicationContext ) ;
}
@Override
public < T > Bindable < T > onStart ( ConfigurationPropertyName name , Bindable < T > target , BindContext context ) {
return isConfigurationProperties ( target . getType ( ) . resolve ( ) )
? target . withBindRestrictions ( BindRestriction . NO_DIRECT_PROPERTY ) : target ;
public Class < ? > getObjectType ( ) {
return ConfigurationPropertiesBinder . class ;
}
private boolean isConfigurationProperties ( Class < ? > target ) {
return target ! = null & & MergedAnnotations . from ( target ) . isPresent ( ConfigurationProperties . class ) ;
@Override
public ConfigurationPropertiesBinder getObject ( ) throws Exception {
Assert . state ( this . binder ! = null , "Binder was not created due to missing setApplicationContext call" ) ;
return this . binder ;
}
}