首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Spring5源码 - 03 普通对象对应的BeanDefinition是如何存入DefaultListableBeanFactory#beanDefinitionMap 源码分析

Spring5源码 - 03 普通对象对应的BeanDefinition是如何存入DefaultListableBeanFactory#beanDefinitionMap 源码分析

作者头像
小小工匠
发布2021-08-17 15:50:40
发布2021-08-17 15:50:40
46700
举报
文章被收录于专栏:小工匠聊架构小工匠聊架构
运行总次数:0


Pre

接上文 Spring5源码 - 02 Bean和Java对象的区别与猜想验证BeanDefinition

我们分析了流程, 也从理论上描述了 普通对象 ----- BeanDefinition ------Bean对象之间的关联,提到了一个BeanDefinition的Map集合 (我们称之为 bdmap ,后面都用这个简称代替 ),

那从源码里面怎么体现出来bdmap 的呢?

本篇博文将带你一一掀开


Spring处理bdmap 的理念

因为这个bdmap 对应Spring太重要了,不仅要处理用户配置的扫描包下的bean,还有一点更重要Spring内置的bean 也需要依靠这个bdmap . 如果这个bdmap 完全交给开发者来处理,比如你把这个map中的数据给remove掉了,等等之类的不可信任的操作,结果可想而知,所以Spring封装了一些API,仅允许开发者通过Spring提供的API来修改bdmap .


源码分析

那我们来看下Spring是如何来封装的这个API呢?

接上文中的 BeanFactoryPostProcessor Bean工厂后置处理器

ConfigurableListableBeanFactory 这个 beanFactory对象 是Spring封装的用于提供给开发者修改BeanDefinition的一个接口类。

提供了 getBeanDefinition 方法

代码语言:javascript
代码运行次数:0
运行
复制
beanFactory.getBeanDefinition("artisan1");

ctrl + alt + b 打开实现类 DefaultListableBeanFactory

我们来看下 定义 beanDefinitionMap

代码语言:javascript
代码运行次数:0
运行
复制
	private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);

Spring也是用的Map来存储的 ~


那我要看 spring是如何把BeanDefinition放到这个 beanDefinitionMap 中的,那我就需要重点观察 beanDefinitionMap 这个对象,Spring是在什么时候赋值的 .

我们知道了 DefaultListableBeanFactory 有个属性 是 beanDefinitionMap

先找DefaultListableBeanFactory

代码语言:javascript
代码运行次数:0
运行
复制
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);

看下AnnotationConfigApplicationContetxt的类关系

跟进去构造函数

代码语言:javascript
代码运行次数:0
运行
复制
	public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
		this();
		register(componentClasses);
		refresh();
	}
  • this() : 调用无参构造函数,会先调用父类GenericApplicationContext的构造函数 ,父类的构造函数里面就是初始化DefaultListableBeanFactory,并且赋值给beanFactory . 本类的构造函数里面,初始化了一个读取器:AnnotatedBeanDefinitionReader read,一个扫描器ClassPathBeanDefinitionScanner scanner . scanner的用处不是很大,它仅仅是在我们外部手动调用 .scan 等方法才有用,常规方式是不会用到scanner对象的 .
  • register(componentClasses): 注册配置类 即 AppConfig.class
  • refresh() : 容器刷新,这个是最核心的方法。 很重要

回到this(),我们来看下源码

代码语言:javascript
代码运行次数:0
运行
复制
public class AnnotationConfigApplicationContext extends GenericApplicationContext implements AnnotationConfigRegistry {}

父类的构造函数

实例化DefaultListableBeanFactory

DefaultListableBeanFactory非常最重要, 主要就是用来生产和获得Bean的


接着子类的构造函数

this.reader = new AnnotatedBeanDefinitionReader(this); 初始化一个Bean读取器

this.scanner = new ClassPathBeanDefinitionScanner(this);初始化一个扫描器,它仅仅是在我们外部手动调用 .scan 等方法才有用,常规方式是不会用到scanner对象的


继续看 new AnnotatedBeanDefinitionReader(this) 实例化建BeanDefinition读取器

代码语言:javascript
代码运行次数:0
运行
复制
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
			BeanDefinitionRegistry registry, @Nullable Object source) {

		DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
		if (beanFactory != null) {
			if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
				//注册了实现Order接口的排序器
				beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
			}
			//设置@AutoWired的候选的解析器
			if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
				beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
			}
		}

		Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);

		/**
		 * 为我们容器中注册了解析我们配置类的后置处理器ConfigurationClassPostProcessor
		 * 名字叫:org.springframework.context.annotation.internalConfigurationAnnotationProcessor
		 */
		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));
		}

		/**
		 * 为我们容器中注册了处理@Autowired 注解的处理器AutowiredAnnotationBeanPostProcessor
		 * 名字叫:org.springframework.context.annotation.internalAutowiredAnnotationProcessor
		 */
		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));
		}

		/**
		 * 为我们容器中注册处理@Required属性的注解处理器RequiredAnnotationBeanPostProcessor
		 * 名字叫:org.springframework.context.annotation.internalRequiredAnnotationProcessor
		 */
		if (!registry.containsBeanDefinition(REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition(RequiredAnnotationBeanPostProcessor.class);
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def, REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
		}

		/**
		 * 为我们容器注册处理JSR规范的注解处理器CommonAnnotationBeanPostProcessor
		 * org.springframework.context.annotation.internalCommonAnnotationProcessor
		 */
		if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
		}

		/**
		 * 处理jpa注解的处理器org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor
		 */
		if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition();
			try {
				def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,
						AnnotationConfigUtils.class.getClassLoader()));
			}
			catch (ClassNotFoundException ex) {
				throw new IllegalStateException(
						"Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);
			}
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
		}

		/**
		 * 处理监听方法的注解解析器EventListenerMethodProcessor
		 */
		if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));
		}

		/**
		 * 注册事件监听器工厂
		 */
		if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));
		}

		return beanDefs;
	}

主要工作

  1. 注册内置BeanPostProcessor 开天辟地的元勋Bean
  2. 注册相关的BeanDefinition

Step1 : this(); 【初始化BeanFactory】

没有呢?我们知道实例化子类,父类也会被初始化,那往上找找吧

可以看到是在父类GenericApplicationContext中初始化的DefaultListableBeanFactory

这样的话,我们把断点打在下面一行 register(componentClasses)上,观察this 中的对象 如下

现在是有默认的Spring初始化的时候自己的BeanDefinition , 没有我们自己的bd ,那就继续走,看看这个beanDefinitionMap什么时候会发生变化~


register(componentClasses); 【注册bean】

先看结论

说明这一步就完成了 从 普通对象 (注册配置类)------- BeanDefinition ----------存入到 bdMap中的操作


接下来分析下核心源码

流程如下

如上 ,这个流程完成后, DefaultListableBeanFactory#beanDefinitionMap 就有了new AnnotationConfigApplicationContext(AppConfig.class)

入参中的 AppConfig.class 对应的Bean了


refresh();

那这个AppConfig配置的扫描包下的bean,什么时候初始化呢? 那就是refresh这个方法了 ,下文继续

先看一眼,结论

这个方法太重要了,一共有12个方法里面, 下篇博文 继续 分析


本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020/09/16 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Pre
  • Spring处理bdmap 的理念
  • 源码分析
    • Step1 : this(); 【初始化BeanFactory】
    • register(componentClasses); 【注册bean】
    • refresh();
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档