Spring源码深度解析02-debug式查看如何加载AnnotationConfig


序言
这是一个一起学习的笔记,也是一个留给自己的笔记,希望之后无论在哪里,能回来看看自己曾经的笔记,看看曾经的自己的。ヾ(≧▽≦*)o
快速了解spring,(spring5.x)

我这边围绕着大纲来一步步走:

  1. 加载配置文件和创建应用上下文
  2. 解析和注册Bean定义
  3. 实例化和依赖注入
  4. 处理Bean的生命周期
  5. 启动应用
  6. 处理AOP和事务

Spring源码深度解析01-debug式看如何加载xml配置文件

加载AnnotationConfig

mian()入口

AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class);
@Configuration
public class MyConfig {
    
    @Bean
    public BeanA beanA() {return new BeanA();}
        
    @Bean
    public BeanB beanB(BeanA beanA) {return new BeanB().set(beanA);}
    
     static class BeanA{}
     static class BeanB{
         private BeanA beanA;
         public BeanB set(BeanA beanA) {this.beanA = beanA;return this;}
         public BeanA get() {return beanA;}
     }
}

AnnotationConfigApplicationContext

public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
	//创建AnnotatedBeanDefinitionReader 创建ClassPathBeanDefinitionScanner
	this();
	//注册class
	register(componentClasses);
	//大名鼎鼎的refresh
	refresh();
}

点击diagrams图 留着,初期看源码不开图,懵逼/(ㄒoㄒ)/~~
在这里插入图片描述

读取类AnnotatedBeanDefinitionReader

点击 this.reader.register()方法,registerBean()方法进到doRegisterBean,

spring中凡是do开头大多都是真正干活的类

/**
 * 省略了注解,记得看
 */	
private <T> void doRegisterBean(Class<T> beanClass, @Nullable String name,
			@Nullable Class<? extends Annotation>[] qualifiers, @Nullable Supplier<T> supplier,
			@Nullable BeanDefinitionCustomizer[] customizers) {

		AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
		if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
			return;
		}

		abd.setInstanceSupplier(supplier);
    	//解析作用域 原始/元数据 默认单例,并设置到bd中
		ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
		abd.setScope(scopeMetadata.getScopeName());
		String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
    	/**
    	* processCommonDefinitionAnnotations
    	* 用于解析通用的注解定义,并根据注解的属性值设置对应的Bean定义属性。
    	* 处理了@Lazy注解的懒加载标志、@Primary注解的主要标志、@DependsOn注解的依赖关系、
    	* @Role注解的角色以及@Description注解的描述,并将这些属性值设置到Bean定义中。
    	*/	
		AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
    	//@Qualifier
		if (qualifiers != null) {
			for (Class<? extends Annotation> qualifier : qualifiers) {
                //@Primary
				if (Primary.class == qualifier) {
					abd.setPrimary(true);
				}
                //@Lazy
				else if (Lazy.class == qualifier) {
					abd.setLazyInit(true);
				}
				else {
                    //提示有限定符需要注意
					abd.addQualifier(new AutowireCandidateQualifier(qualifier));
				}
			}
		}
    	//上面代码的目的是根据不同的限定符,对abd进行不同的设置,以确保正确的Bean被注入。
		if (customizers != null) {
			for (BeanDefinitionCustomizer customizer : customizers) {
				customizer.customize(abd);
			}
		}

		BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
    	//根据作用域代理模式,为Bean定义创建适当的代理,并将代理注册到Bean定义注册表中。这样,当获取该作用域的Bean实例时,实际上获取到的是代理对象。默认是 NO
		definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
    	/**
    	 * 判断是否存在 existingDefinition
    	 * 判断是否创建中 hasBeanCreationStarted
    	 * 注册bean到 beanDefinitionMap
    	 * 添加beanName到 beanDefinitionNames
    	 * 注册后需要删除手动注册方式注册到spring context上 singleton bean name
    	 * 可能是防止冲突或错误
    	 */
		BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
    //等待refresh
	}

之后就是refresh方法

小结

AnnotationConfig源码读取比XML读取的方法较为清晰

AnnotationConfig父类GenericApplicationContext和ClassPathXmlApplicationContext父类AbstractXmlApplicationContext
是Spring Framework中的两个应用程序上下文的实现类。
共同点:

  1. 都是应用程序上下文的具体实现类,用于管理和组织Spring应用程序的Bean。
  2. 都继承自抽象类ApplicationContext,并实现了相应的接口,提供了通用的上下文功能,如Bean的注册、获取、生命周期管理等。

不同点:

  1. GenericApplicationContext是一个通用的应用程序上下文,支持多种方式的Bean定义加载,如通过XML、注解、Java配置等。它的加载方式更加灵活,可以根据需要选择合适的方式加载Bean定义。

    AbstractXmlApplicationContext是基于XML配置的应用程序上下文,专门用于加载和解析XML格式的Bean定义。它通过解析XML文件来创建和配置Bean实例。

  2. GenericApplicationContext的配置方式更为灵活,可以通过编程的方式进行配置,可以在运行时动态地注册和修改Bean定义。

    AbstractXmlApplicationContext的配置方式是静态的,需要提前将Bean定义配置在XML文件中,然后通过解析XML文件来完成上下文的初始化。

  3. GenericApplicationContext可以与不同类型的Bean定义读取器(如AnnotatedBeanDefinitionReader、ClassPathBeanDefinitionScanner等)结合使用,以支持不同的加载方式。

    AbstractXmlApplicationContext内部使用XmlBeanDefinitionReader来解析XML文件,并加载XML中定义的Bean。

GenericApplicationContext是从Spring Framework 2.5版本引入的,它是一个通用的应用程序上下文实现,可以用于加载和管理各种类型的Bean定义,包括XML、注解和Java配置等。

AbstractXmlApplicationContext是早期版本的Spring Framework中的一个应用程序上下文实现,它专门用于加载和解析基于XML配置的Bean定义。

小结:

GenericApplicationContext是一个通用且灵活的应用程序上下文,可以支持多种方式的Bean定义加载,而AbstractXmlApplicationContext则是基于XML配置的应用程序上下文,专注于加载和解析XML格式的Bean定义。

求求大哥们给个三连吧,真的是一行行怼的 >︿<

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小小大凳子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值