spring源码-AnnotationConfigApplicationContext的AnnotatedBeanDefinitionReader分支

spring源码的解读
我们首先编译得到spring的源代码,然后我们创建一个测试类测试创建spring容器

我们进入AnnotationConfigApplicationContext构造函数,最重要的就是这三个函数

进入到this去调用本类的无参构造并初始化父类,我们首先来看this分支他做了什么?
他给reader和scanner做了创建对象并赋值,我们先走进AnnotatedBeanDefinitionReader看看到底做了什么

registry是我们的AnnotationConfigApplicationContext实例,getOrCreateEnvironment方法获得了envproperties和systempropertis
不信进入看看
从这开始getOrCreateEnvironment方法

他判断AnnotationConfigApplicationContext是否是EnvironmentCapable的子类,那么是的,可以找到
AnnotationConfigApplicationContext->GenericApplicationContext->AbstractApplicationContext->ConfigurableApplicationContext->ApplicationContext->EnvironmentCapable
这样一个关系
image

那么这里就是重新执行AbstractApplicationContext的getEnvironment方法

这里做了一个createEnv方法,我们进入能够看到new了一个标准环境对象

再进入发现这个类没有构造函数,那么就是隐式调用父类AbstractEnvironment的构造函数
然后customizePropertySources方法是没有函数体的方法,那么还是会调用到子类StandardEnvironment的customizePropertySources方法
这里propertySources就是环境的list,我们在这里加入了两个环境源,举例说明一个加入了系统环境,一个加入了env环境

到这结束getOrCreateEnvironment方法
我们继续回来看this方法

从这里开始是new ConditionEvaluator
他将AnnotationConfigApplicationContext实例进行了赋值,再去创建一个条件分析对象,并传入了AnnotationConfigApplicationContext实例和环境

再过来做赋值操作,然后就是各种reduce方法去创建工厂

前面getOrCreateEnvironment方法中提到过AnnotationConfigApplicationContext的层级关系
AnnotationConfigApplicationContext->GenericApplicationContext->ConfigurableApplicationContext
那么同样的,这里还是由子类去执行getBeanFactory方法,这里我们能够找到的子实现类是

他返回了我们的beanFactory

这个beanFactory就是我们核心的

所以这一段的reduce这类的函数都是在赋值一些我们需要的类,比如生成加载器,bean工厂,环境之类的,并且不产生返回值
到这结束new ConditionEvaluator 没有返回值,那这个方法不就是类似于配置环境吗?
让我们回到reader的构造函数中
image
我们进入这个方法看看他里面是做了什么
image
再进
从这里开始是reader的核心功能,将spring的一些常见的beanDefinition进行加载到beanFactory中registerAnnotationConfigProcessors
image
这一个方法很长很核心,我们慢慢来看,先看unwrapDefaultListableBeanFactory方法,进入看看他在干嘛
image
还是一样的,AnnotationConfigApplicationContext不是DefaultListableBeanFactory子类,他不会进入if判断中,这里还是会获取到GenericApplicationContext初始化的defaultListableBeanFactory,return出来
image
下面这两个结构类似,我就只讲解一个了
这时候我们才刚创建容器,所以是肯定没有beanFactory.getDependencyComparator()的,那么他就会给我们创建并且设置上AnnotationAwareOrderComparator,那么他是用来干什么的呢?
image
提供对支持@order和@Priority注解的,扫描order和priority的注解
ok那么第一个是提供对order和priority的支持,第二个是提供@Lazy和他的父类@Qualifier和@Value注解的
那么这是这两个判断的作用
再往下,长图借不了,我放在代码块中

点击查看代码
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
			BeanDefinitionRegistry registry, @Nullable Object source) {

		DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
		if (beanFactory != null) {
			if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
				beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
			}
			if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
				beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
			}
		}

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

		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));
		}

		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));
		}

		// Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.
		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));
		}

		// Check for JPA support, and if present add the 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));
		}

		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;
	}
这里的结构也都类似,我们只看一个即可 先看BeanDefinitionHolder里面存放了什么?

image

往下

image
是创建一个internalConfigurationAnnotationProcessor
我们刚开始创建容器,所以肯定是没有的,所以会进入到判断语句中
去创建rootDefinition设置一下信息
然后注意registerPostProcessor方法
image
set一下角色,用于标记一个 BeanDefinition 的角色,0是表示该 Bean 是 用户定义的业务 Bean(如 @Service, @Component 等)。1表示该 Bean 是 支持性组件(如 AOP 代理、事务拦截器等)2表示该 Bean 是 Spring 框架内部的基础设施 Bean(如 BeanPostProcessor、BeanFactoryPostProcessor 等)。
然后去registerBeanDefinition注册beanDefinition,他是调用了接口方法,执行了GenericApplicationContext子类的方法
image
这里的beanFactory就是核心DefaultListableBeanFactory
image
其实这个validate不是很重要,因为与他相关的是两个不再使用的bean,所以可以忽略
第一次创建容器所以可以直接跳过判断
image
做哪个beanDefinition的注册呢?我们debug一下
image
原来是这个,那么我们就知道了,这个结构几个类似的都是在做几个spring的内部beanDefinition的创建,如下图这些bean
image
到此为止registerAnnotationConfigProcessors结束

总结

AnnotationConfigApplicationContext中的AnnotatedBeanDefinitionReader分支,他就是做了一个环境的载入,以及spring容器启动所需beanDefinition的注册,扫描一下@lazy,@order,@priority,@Qualifier,@Value这些注解,增加核心注解的支持,不处理componentScan注解,这个交由下一篇要讲的分支来做

这次没注意到markdown文件不好用,下次改换html编辑器了

posted @ 2025-05-19 16:07  七森星罗  阅读(34)  评论(0)    收藏  举报