AnnotatedBeanDefinitionReader解析内置处理器为BeanDefinition并注册

本文是Spring系列文章的一部分。其他相关文章见

Spring系列文章导航

本文详解AnnotatedBeanDefinitionReader解析内置处理器为BeanDefinition并注册的全过程。


前言

前文提到AnnotationConfigApplicationContext的构造器中调用三个方法,第一个是this(),this()的第一步是创建一个BeanFactory,this()的第二步是创建一个reader,第三步是创建一个scanner
本文详解第二步。


一、 注册内置BeanPostProcessor

这是全系列文章中第一次提到后置处理器,这里不会太难,如果看不懂,可以先顺一遍,后边一定要回顾,这是Spring的核心。

跟着this()跟到AnnotatedBeanDefinitionReader的构造器,直接看最后一行代码,意思非常清楚,注册注解配置类的处理器。

public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
		Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
		Assert.notNull(environment, "Environment must not be null");
		this.registry = registry;
		this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
		AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
	}

进入

	public static void registerAnnotationConfigProcessors(BeanDefinitionRegistry registry) {
		registerAnnotationConfigProcessors(registry, null);
	}

再进入,之后有一些关键的代码,我列出部分,不是说别的都不重要,而是,我列出的部分已经可以串成一条线。

1.判断是否已注册配置类的注解处理器

		if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
		}

Spring的命名非常完整,可以清楚的看明白他的意图。
本段代码就是说如果还没有注册处理器,那么就注册他。
不要把处理器看的太过于复杂,他也是个类,在Spring容器中,他也需要先被解析成BeanDefinition,然后被注册。只不过处理器是由容器统一调用的,而我们的类是我们自己调用的。
ConfigurationClassPostProcessor是用于解析 @configuration注解的。

2.判断是否已注册自动装配的注解处理器

if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
		}

3.我要忽略其他部分

如果读者同时也在跟源码,那么会发现后边就是事件监听的处理器注册。绝对非常重要,但是,不在我们这条线上,我后边监听器部分会串另一条线,这里解释一下,让读者了解我的写作风格。

二、 注册相关的BeanDefinition

进入注册后置处理器的方法中。

	private static BeanDefinitionHolder registerPostProcessor(
			BeanDefinitionRegistry registry, RootBeanDefinition definition, String beanName) {

		definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
		registry.registerBeanDefinition(beanName, definition);
		return new BeanDefinitionHolder(definition, beanName);
	}

可以看到注册BeanDefiniton的调用。

跟进去的时候发现这是个接口的方法,他的实现类是GenericApplicationContext,这是注解容器AnnotationConfigApplicationContext的父类。

进入,可以看到就一句,向beanFactory注册BeanDefiniton。

	public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
			throws BeanDefinitionStoreException {
		this.beanFactory.registerBeanDefinition(beanName, beanDefinition);
	}

再进入,会发现里面有大量的处理各种逻辑分支,各种异常的代码,但是最重要的只有两句。

//向map中注入<beanName, beanDefinition>的映射
this.beanDefinitionMap.put(beanName, beanDefinition);
//向set中注入beanName元素
this.beanDefinitionNames.add(beanName);

总结

Spring源码就像迷宫,如果你能拿到一幅地图,走出来实在太轻松了,因为他里面的命名实在太清楚了。但是,所有的课程书籍都会说,一定要抓住主线,其实也是我前边想传递的一个想法。就以事件监听器部分为例,确实很重要,但是在我们这条主线上,也是可以不看的,那就先不看。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值