序言
这是一个一起学习的笔记,也是一个留给自己的笔记,希望之后无论在哪里,能回来看看自己曾经的笔记,看看曾经的自己的。ヾ(≧▽≦*)o
快速了解spring,(spring5.x)
我这边围绕着大纲来一步步走:
- 加载配置文件和创建应用上下文
- 解析和注册Bean定义
- 实例化和依赖注入
- 处理Bean的生命周期
- 启动应用
- 处理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中的两个应用程序上下文的实现类。
共同点:
- 都是应用程序上下文的具体实现类,用于管理和组织Spring应用程序的Bean。
- 都继承自抽象类ApplicationContext,并实现了相应的接口,提供了通用的上下文功能,如Bean的注册、获取、生命周期管理等。
不同点:
-
GenericApplicationContext
是一个通用的应用程序上下文,支持多种方式的Bean定义加载,如通过XML、注解、Java配置等。它的加载方式更加灵活,可以根据需要选择合适的方式加载Bean定义。AbstractXmlApplicationContext
是基于XML配置的应用程序上下文,专门用于加载和解析XML格式的Bean定义。它通过解析XML文件来创建和配置Bean实例。 -
GenericApplicationContext
的配置方式更为灵活,可以通过编程的方式进行配置,可以在运行时动态地注册和修改Bean定义。AbstractXmlApplicationContext
的配置方式是静态的,需要提前将Bean定义配置在XML文件中,然后通过解析XML文件来完成上下文的初始化。 -
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定义。
求求大哥们给个三连吧,真的是一行行怼的 >︿<