spring 源码系列(五)- 最重要的后置处理器ConfigurationClassPostProcessor

1 介绍

一句话总结:
ConfigurationClassPostProcessor的作用是将BeanDefinitionRegistry中的所有BeanDefinition重新提取出来,然后寻找这些BeanDefinition是否是标记有下面6种注解,(因为这些注解类的内部可能还有的别的BeanDefinition),有的话就将它们提取出来,封装成BeanDefinition注册到BeanDefinitionRegistry中。

ConfigurationClassPostProcessor用于对@Configuration类进行解析。
实际上不止@Configuration,该处理器会对容器中含有以下注解的bean进行处理:

  1. @Configuration
  2. @Component:注意,@Service、@Controller等一些注释本身其实也是@Component
  3. @ComponentScan
  4. @Import
  5. @ImportResource
  6. @PropertySource:会将其解析成PropertySource类然后存入environment中

这里还需要注意,第2-5点会被处理器标记属性为Lite,而@Configuration会被标记属性为Full。

功能:解析@Configuration等注释的类,将其所含有的其他bean注册到beanDefinitionMap中

该功能的对应方法是postProcessBeanDefinitionRegistry()

这里用代码例子进行简要的介绍:
先定义一个Config类

@Configuration
public class PeopleConfig {
    @Bean(name="person1")
    public Person person1() {
        Person person= new Person();
        person.setName("person1");
        return person;
    }

    @Bean(name="person2")
    public Person person2() {
        Person person= new Person();
        person.setName("person2");
        return person;
    }

    public static void main(String[] args){
    	ApplicationContext context = new AnnotationConfigApplicationContext(PeopleConfig.class);
    }
}

调用ConfigurationClassPostProcessor进行后置处理前,beanDefinitionMap含有PeopleConfig,但不含有person1和person2:

后置处理后,beanDefinitionMap含有了person1和person2这两个bean的beanDefinition:

实际上,除了@Configuration外,其他注解也是可以的,以@ComponentScan为例:

@ComponentScan("com.test")
public class PeopleConfig {

}

后置处理器操作前:

后置处理器操作后如下图所示,可以看到多了好几个beanDefinition:
在这里插入图片描述

而对于@PropertySource这个注解,会将注解中对应的文件解析成PropertySource中并放入environment中。

具体的原理见下方的“原理篇”。

2 原理

2.1 预备知识

阅读下面的文章之前,需要对Spring 的metadata有足够的了解,详见我的另一篇博客:
spring 之 元数据metadata

2.2 原理

关于ConfigurationClassPostProcessor,个人推荐下面这篇文章,作者有很用心地去介绍这个后置处理器:
ConfigurationClassPostProcessor —— Spring中最!最!最!重要的后置处理器!没有之一!!!

补充:
2.2.1 文中也存在一些错误(个人观点),这里记录一下:

第2点 postProcessBeanDefinitionRegistry()的代码中,关于parser.parse(candidates);方法的注释有问题:这一步并不会将将加了@Configuration注解的类加到beanDefinitionMap中,然而在具体代码中,并没有看到这一步操作。

而对@Configuration类进行增强那段,因为我@Configuration用的比较简单,所以对这部分理解的不是很透彻。

2.2.2 @Configuration的情况

另外,对于@Configuration的情况,解析的方式是获得该类的AnnotationMetaData,然后再调用getAnnotatedMethods()获取@Bean的所有方法的MethodMetadata。

		AnnotationMetadata original = sourceClass.getMetadata();
		Set<MethodMetadata> beanMethods = original.getAnnotatedMethods(Bean.class.getName());
2.3 流程图

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值