基于Spring注解的上下文初始化过程源码解析(一)
最近工作之余有时间和精力,加上平时对源码比较感兴趣,就开始啃起了spring源码。为加深印象写了这篇博客,如有错误,望各位大佬不吝指正。
我看的是spring5的源码,从同性社区download下来后编译,然后看源码、写注释、一步一步debug,理论指导实践,实践再反作用于理论。
因为基于注解的开发是现在比较主流的开发模式,所以就从 annotationconfigapplicationcontext 开始啃了。
因为代码过多,执行流程过于复杂,就拆成了三篇来解析。
下面就从这个类开始探究spring上下文的初始化。
这里需要留意 annotationconfigapplicationcontext 继承了 genericapplicationcontext
public class genericapplicationcontext extends abstractapplicationcontext implements beandefinitionregistry {
private final defaultlistablebeanfactory beanfactory;
/**
* 注意这个无参构造函数
*
* 这个初始化的defaultlistablebeanfactory就是spring的bean工厂
*/
public genericapplicationcontext() {
this.beanfactory = new defaultlistablebeanfactory();
}
}
再来看看 annotationconfigapplicationcontext 这个类
public class annotationconfigapplicationcontext extends genericapplicationcontext implements annotationconfigregistry {
/**
* 定义一个读取注解的 beandefinition 读取器
* 这个类在构造方法中被实例化
*/
private final annotatedbeandefinitionreader reader;
/**
* 定义一个扫描类路径下加了注解的 beandefinition 扫描器
* 这个类在构造方法中被实例化
*/
private final classpathbeandefinitionscanner scanner;
public annotationconfigapplicationcontext() {
// 实例化 beandefinition 读取器
/**
* 注册所有注解相关的后置处理器
* 最重要的一个后置处理器 configurationclasspostprocessor
* beanname 是 internalconfigurationannotationprocessor
*/
this.reader = new annotatedbeandefinitionreader(this);
// 实例化 beandefinition 扫描器
// 但是实际上扫描包的工作并不是 scanner 这个对象来完成的,是 spring 自己创建的一个新的 classpathbeandefinitionscanner
// 这里的 scanner 仅仅是为了程序员能够在外部调用 annotationconfigapplicationcontext 对象的 scanner 方法
this.scanner = new classpathbeandefinitionscanner(this);
}
public annotationconfigapplicationcontext(defaultlistablebeanfactory beanfactory) {
// 调用父类的构造方法,初始化 defaultlistablebeanfactory 的 bean 工厂
super(beanfactory);
// 实例化该读取器
this.reader = new annotatedbeandefinitionreader(this);
// 实例化该扫描器
this.scanner = new classpathbeandefinitionscanner(this);
}
/**
* 这个构造方法需要传入一个 @configuration 注解配置类
* 通过注解读取器读取并解析
*/
public annotationconfigapplicationcontext(class<?>... annotatedclasses) {
/**
* 由于继承了父类,这里会先去调用父类的构造方法,然后调用自身的构造方法
*
* this.beanfactory = new defaultlistablebeanfactory();
*
* 其实就是初始化一个 defaultlistablebeanfactory
*/
this();
/**
* 将传入的 @configuration 配置类转换为 beandefinition
* 并添加到 defaultlistablebeanfactory 工厂的 beandefinitionmap 中
*/
register(annotatedclasses);
/**
* 1、准备刷新山下文
* 2、通知子类刷新内部的 bean 工厂,得到创建的 defaultlistablebeanfactory 工厂
* 3、配置工厂的标准上下文特征
* 4、允许在上下文子类中对 bean 工厂进行后置处理
* 5、在上下文中调用工厂处理器方法,注册为 bean
* 6、注册 beanpostprocessor
* 7、初始化此上下文的消息源
* 8、初始化应用事件广播器【springboot 的启动源码中与该方法有很大关系】
* 9、在特定的上下文子类中初始化其他特殊 bean
* 10、检查监听器 bean 并注册它们
* 11、实例化所有剩余(非延迟初始化)单例
* 12、发布相应的事件
*/
refresh();
}
public annotationconfigapplicationcontext(string... basepackages) {
/**
* 由于继承了父类,这里会先去调用父类的构造方法,然后调用自身的构造方法
*
* this.beanfactory = new defaultlistablebeanfactory();
*
* 其实就是初始化一个 defaultlistablebeanfactory
*/
this();
scan(basepackages);
refresh();
}
}
这里还要注意一下annotatedbeandefinitionreader的实例化,代码跟进去发现调用了 annotationconfigutils 的 registerannotationconfigprocessors 方法,spring在初始化上下文时,在bean工厂中添加了很多辅助其初始化的类
public static set<beandefinitionholder> registerannotationconfigprocessors(
beandefinitionregistry registry, @nullable object source) {
// 获取 bean 工厂
defaultlistablebeanfactory beanfactory = unwrapdefaultlistablebeanfactory(registry);
if (beanfactory != null) {
if (!(beanfactory.getdependencycomparator() instanceof annotationawareordercomparator)) {
// annotationawareordercomparator 主要能解析 @order 注解和 @priority 注解
beanfactory.setdependencycomparator(annotationawareordercomparator.instance);
}
if (!(beanfactory.getautowirecandidateresolver() instanceof contextannotationautowirecandidateresolver)) {
// contextannotationautowirecandidateresolver 提供处理延迟加载的功能
beanfactory.setautowirecandidateresolver(new contextannotationautowirecandidateresolver());
}
}
/**
* 存放所有辅助类的信息
*/
set<beandefinitionholder> beandefs = new linkedhashset<>(8);
/**
* beandefinition 的注册,很重要,需要理解注册的每个 bean 的类型和作用
*
* spring 在初始化 applicationcontext 和 bean 工厂时,在 bean 工厂中添加了很多辅助初始化 bean 工厂的类
*
* 1.configurationclasspostprocessor 类型是 beanfactorypostprocessor
* 2.autowiredannotationbeanpostprocessor 类型是 beanpostprocessor
* 3.commonannotationbeanpostprocessor 类型是 beanpostprocessor
* 4.persistenceannotationbeanpostprocessor 类型是 beanpostprocessor
* 5.eventlistenermethodprocessor 类型是 beanfactorypostprocessor
* 6.defaulteventlistenerfactory 类型是 eventlistenerfactory
*/
/**
* beanname 是否包含 org.springframework.context.annotation.internalconfigurationannotationprocessor
* beanclass 是 configurationclasspostprocessor,类型是 beanfactorypostprocessor
*/
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));
}
/**
* beanname 是否包含 org.springframework.context.annotation.internalautowiredannotationprocessor
* beanclass 是 autowiredannotationbeanpostprocessor,类型是 beanpostprocessor
*/
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.
/**
* beanname 是否包含 org.springframework.context.annotation.internalcommonannotationprocessor
* beanclass 是 commonannotationbeanpostprocessor,类型是 beanpostprocessor
*/
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.
/**
* 检查 jpa 支持,如果存在,则添加 persistenceannotationbeanpostprocessor
*
* beanname 是否包含 org.springframework.context.annotation.internalpersistenceannotationprocessor
* beanclass 是 persistenceannotationbeanpostprocessor,类型是 beanpostprocessor
*/
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));
}
/**
* beanname 是否包含 org.springframework.context.event.internaleventlistenerprocessor
* beanclass 是 eventlistenermethodprocessor,类型是 beanfactorypostprocessor
*/
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));
}
/**
* beanname 是否包含 org.springframework.context.event.internaleventlistenerfactory
* beanclass 是 defaulteventlistenerfactory,类型是 eventlistenerfactory
*/
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;
}
这个方法执行完后,可以看到 defaultlistablebeanfactory 中的 beandefinitionmap 中已经有数据了,如果支持 jpa 则有6个元素,没有则有5个。分别是 configurationclasspostprocessor、autowiredannotationbeanpostprocessor、commonannotationbeanpostprocessor、eventlistenermethodprocessor、defaulteventlistenerfactory,支持 jpa 的是 persistenceannotationbeanpostprocessor。
这里实例化的 classpathbeandefinitionscanner 仅仅是为了让程序员能够在外部调用 annotationconfigapplicationcontext 对象的 scanner 方法。spring 在后面又重新初始化了一个 classpathbeandefinitionscanner,用新的 classpathbeandefinitionscanner 进行扫描。
回到一开始,我这里是传了一个@configuration的配置类,所以从register方法往下跟,最后调用的是 annotatedbeandefinitionreader 的 doregisterbean 方法
/**
* 将给定的 bean 类注册为 bean,从类声明的注释中派生其元数据
*/
private <t> void doregisterbean(class<t> annotatedclass, @nullable string name,
@nullable class<? extends annotation>[] qualifiers,
@nullable supplier<t> supplier, @nullable beandefinitioncustomizer[] customizers) {
// 根据指定的 bean 创建一个 annotatedgenericbeandefinition
annotatedgenericbeandefinition abd = new annotatedgenericbeandefinition(annotatedclass);
// 若这个类是需要跳过解析的类,则返回
if (this.conditionevaluator.shouldskip(abd.getmetadata())) {
return;
}
// 指定创建 bean 实例的回调方法,此时为 null
abd.setinstancesupplier(supplier);
// 解析类的作用域元数据
scopemetadata scopemetadata = this.scopemetadataresolver.resolvescopemetadata(abd);
// 添加类的作用域元数据
abd.setscope(scopemetadata.getscopename());
/**
* 生成 beanname
* 调用 annotationbeannamegenerator.generatebeanname()
*/
string beanname = (name != null ? name : this.beannamegenerator.generatebeanname(abd, this.registry));
/**
* 处理类当中的通用注解
* 主要处理 @lazy @dependson @primary @role @description 等注解
* 处理完成之后将值赋给到 annotatedgenericbeandefinition 对应的属性中
*/
annotationconfigutils.processcommondefinitionannotations(abd);
/**
* 如果在向容器注册注解 beandefinition 时,使用了额外的限定符注解则解析
* byname 和 qualifiers 变量是 annotation 类型的数组,里面不仅存了 @qualifier 注解
* 所以 spring 遍历这个数组判断是否加了指定注解
*
* 此时 qualifiers 为 null,if 语句不执行
*/
if (qualifiers != null) {
for (class<? extends annotation> qualifier : qualifiers) {
if (primary.class == qualifier) {
// 设置 primary 属性值
abd.setprimary(true);
} else if (lazy.class == qualifier) {
// 设置 lazyinit 属性值
abd.setlazyinit(true);
} else {
/**
* 如果使用了除 @primary 和 @lazy 以外的其他注解
* 则为该 bean 添加一个根据名字自动装配的限定符
*/
// 向 map<string, autowirecandidatequalifier> qualifiers 集合中添加值
abd.addqualifier(new autowirecandidatequalifier(qualifier));
}
}
}
/**
* 如果存在一个或多个用于自定义工厂的回调
*
* 此时 customizers 为 null,if 语句不执行
*/
if (customizers != null) {
for (beandefinitioncustomizer customizer : customizers) {
customizer.customize(abd);
}
}
/**
* 获取 beandefinitionholder 持有者容器
* 里面包含的属性值有 string beanname,beandefinition beandefinition 和 string[] aliases 别名集合
*/
beandefinitionholder definitionholder = new beandefinitionholder(abd, beanname);
/**
* 解析代理模型
*/
definitionholder = annotationconfigutils.applyscopedproxymode(scopemetadata, definitionholder, this.registry);
/**
* 将最终获取到的 beandefinitionholder 持有者容器中包含的信息注册给 beandefinitionregistry
*
* annotationconfigapplicationcontext 在初始化的时候通过调用父类的构造方法,实例化了一个 defaultlistablebeanfactory
* 这一步就是把 beandefinitionholder 这个数据结构中包含的信息注册到 defaultlistablebeanfactory 中
*
* defaultlistablebeanfactory 实现了 beandefinitionregistry
*
* 此时传入的 @configuration 配置类已经注册到 defaultlistablebeanfactory 工厂中
*/
beandefinitionreaderutils.registerbeandefinition(definitionholder, this.registry);
}
这里比较重要的是最后一行代码,进行注册操作,代码如下:
public static void registerbeandefinition(
beandefinitionholder definitionholder, beandefinitionregistry registry)
throws beandefinitionstoreexception {
// register bean definition under primary name.
// 用类的主要名称注册 beandefinition
string beanname = definitionholder.getbeanname();
/**
* 将 beanname 注册到 defaultlistablebeanfactory 工厂中
*/
registry.registerbeandefinition(beanname, definitionholder.getbeandefinition());
// register aliases for bean name, if any.
// 如果有别名则为 beanname 注册别名
string[] aliases = definitionholder.getaliases();
if (aliases != null) {
for (string alias : aliases) {
/**
* 注册别名
*/
registry.registeralias(beanname, alias);
}
}
}
public void registerbeandefinition(string beanname, beandefinition beandefinition)
throws beandefinitionstoreexception {
if (beandefinition instanceof abstractbeandefinition) {
try {
((abstractbeandefinition) beandefinition).validate();
} catch (beandefinitionvalidationexception ex) {
throw new beandefinitionstoreexception(beandefinition.getresourcedescription(), beanname,
"validation of bean definition failed", ex);
}
}
// 先从 map<string, beandefinition> beandefinitionmap 中获取一次
beandefinition existingdefinition = this.beandefinitionmap.get(beanname);
// 已注册过则进行逻辑校验
if (existingdefinition != null) {
// 是否允许 beandefinition 覆盖
if (!isallowbeandefinitionoverriding()) {
// 不允许则抛异常
throw new beandefinitionoverrideexception(beanname, beandefinition, existingdefinition);
}
// 已存在的角色是否小于传入的 beandefinition 角色
else if (existingdefinition.getrole() < beandefinition.getrole()) {
// e.g. was role_application, now overriding with role_support or role_infrastructure
if (logger.isinfoenabled()) {
logger.info("overriding user-defined bean definition for bean '" + beanname +
"' with a framework-generated bean definition: replacing [" +
existingdefinition + "] with [" + beandefinition + "]");
}
}
// 如果传入的 beandefinition 和已存在的不相等
else if (!beandefinition.equals(existingdefinition)) {
if (logger.isdebugenabled()) {
logger.debug("overriding bean definition for bean '" + beanname +
"' with a different definition: replacing [" + existingdefinition +
"] with [" + beandefinition + "]");
}
} else {
if (logger.istraceenabled()) {
logger.trace("overriding bean definition for bean '" + beanname +
"' with an equivalent definition: replacing [" + existingdefinition +
"] with [" + beandefinition + "]");
}
}
// 重新存入 map<string, beandefinition> beandefinitionmap 中
this.beandefinitionmap.put(beanname, beandefinition);
}
// 不存在
else {
// 是否已经启动 bean 创建
if (hasbeancreationstarted()) {
// cannot modify startup-time collection elements anymore (for stable iteration)
synchronized (this.beandefinitionmap) {
// 注册到 map<string, beandefinition> beandefinitionmap 集合中
this.beandefinitionmap.put(beanname, beandefinition);
// 用新的 beandefinitionnames 替换旧的
list<string> updateddefinitions = new arraylist<>(this.beandefinitionnames.size() + 1);
updateddefinitions.addall(this.beandefinitionnames);
updateddefinitions.add(beanname);
this.beandefinitionnames = updateddefinitions;
// 从集合中移除该 bean 名称
removemanualsingletonname(beanname);
}
}
// 还未启动 bean 创建,即仍在启动注册阶段
else {
// 注册到 map<string, beandefinition> beandefinitionmap 集合中
this.beandefinitionmap.put(beanname, beandefinition);
// 添加 bean 名称到 beandefinitionnames 数据集合中
this.beandefinitionnames.add(beanname);
// 从集合中移除该 bean 名称
removemanualsingletonname(beanname);
}
this.frozenbeandefinitionnames = null;
}
if (existingdefinition != null || containssingleton(beanname)) {
resetbeandefinition(beanname);
}
}
register 方法执行完成,此时传入的 @configuration 配置类已经注册到 defaultlistablebeanfactory 工厂中
那这一篇就先到这里,有问题或者错误欢迎大家沟通交流
下一篇从 refresh 方法开始往下跟代码
下一篇: Spring-使用注解实现AOP(九)