spring @EnableConfigurationProperties 实现原理

查看DataSourceAutoConfiguration源码,发现如下代码:
@Configuration
@ConditionalOnClass({ DataSource.class, EmbeddedDatabaseType.class })
@EnableConfigurationProperties(DataSourceProperties.class)
@Import({ DataSourcePoolMetadataProvidersConfiguration.class,
        DataSourceInitializationConfiguration.class })
public class DataSourceAutoConfiguration {
//其它代码省略
}

关键点:@EnableConfigurationProperties(DataSourceProperties.class)

 

进入:@EnableConfigurationProperties
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(EnableConfigurationPropertiesImportSelector.class)
public @interface EnableConfigurationProperties {

    /**
     * Convenient way to quickly register {@link ConfigurationProperties} annotated beans
     * with Spring. Standard Spring Beans will also be scanned regardless of this value.
     * @return {@link ConfigurationProperties} annotated beans to register
     */
    Class<?>[] value() default {};

}

关键点:@Import(EnableConfigurationPropertiesImportSelector.class)

 

查看:EnableConfigurationPropertiesImportSelector
class EnableConfigurationPropertiesImportSelector implements ImportSelector {

    private static final String[] IMPORTS = {
            ConfigurationPropertiesBeanRegistrar.class.getName(),
            ConfigurationPropertiesBindingPostProcessorRegistrar.class.getName() };

    @Override
    public String[] selectImports(AnnotationMetadata metadata) {
        return IMPORTS;
    }
//其它省略
}
关键点:return IMPORTS; 其中包含:ConfigurationPropertiesBeanRegistrar、ConfigurationPropertiesBindingPostProcessorRegistrar

 

查看:ConfigurationPropertiesBeanRegistrar
public static class ConfigurationPropertiesBeanRegistrar
            implements ImportBeanDefinitionRegistrar {

        @Override
        public void registerBeanDefinitions(AnnotationMetadata metadata,
                BeanDefinitionRegistry registry) {
            getTypes(metadata).forEach((type) -> register(registry,
                    (ConfigurableListableBeanFactory) registry, type));
        }
//其它省略
}
作用:向BeanFactory注册了一个Bean,类型为DataSourceProperties,这就是为什么可以用AutoWire得到这个属性文件的原因(被注入成一个bean了)
状态说明:此时注册的DataSourceProperties类只是一个简单bean注册,类中的属性是怎样被赋值的呢?请看下一步

 

查看:ConfigurationPropertiesBindingPostProcessorRegistrar
public class ConfigurationPropertiesBindingPostProcessorRegistrar
        implements ImportBeanDefinitionRegistrar {

    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata,
            BeanDefinitionRegistry registry) {
        if (!registry.containsBeanDefinition(
                ConfigurationPropertiesBindingPostProcessor.BEAN_NAME)) {
            registerConfigurationPropertiesBindingPostProcessor(registry);
            registerConfigurationBeanFactoryMetadata(registry);
        }
    }
//其它省略
}
关键点:
作用:检查BeanFoctory是否有Bean:ConfigurationBeanFactoryMetadata(BeanFactoryPostProcessor)、ConfigurationPropertiesBindingPostProcessor(BeanPostProcessor),
如果没有就注册这两个Bean
状态说明:这个时时候已经很明显了,在上一步是往BeanFactory注册了一个DataSourceProperties的bean,但是属性值是空的,那属性被赋值肯定就是被这两个后置处理器处理的

 

查看:ConfigurationBeanFactoryMetadata
作用:没看出什么太大作用,继续下一步

 

查看:ConfigurationPropertiesBindingPostProcessor
@Override
    public Object postProcessBeforeInitialization(Object bean, String beanName)
            throws BeansException {
        ConfigurationProperties annotation = getAnnotation(bean, beanName,
                ConfigurationProperties.class);
        if (annotation != null) {
            bind(bean, beanName, annotation);
        }
        return bean;
    }
关键点:实现了BeanPostProcessor.postProcessBeforeInitialization方法,此时DataSourceProperties的各个属性值就是在这里进行赋值的
作用:对DataSourceProperties的属性进行赋值,方法是bind(bean, beanName, annotation),处理操作应该是读取配置文件进行解析然后赋值到DataSourceProperties属性中,详细过程可查看源码

 

总结:spring中各种方便的功能基本都是环绕spring生命周期进行扩展,如实现ImportBeanDefinitionRegistrar注册bean,

实现BeanFactoryPostProcessor修改bean定义或者是生成新的bean以及BeanPostProcessor,在BeanPostProcessor中进行Bean的内部处理

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值