前言
趁着假期 && 疫情, 沉淀一下
废话不多说,直奔正题。
Spring的核心,即IOC和AOP,本篇文章其实就是来分析下 Spring 的 IOC 容器,IOC又叫控制反转,把对象以Bean的形式交给IOC去管理,由Spring去管理对象的生命周期,使得Bean与Bean之间的松耦合。
Spring的注解启动类
进入 AnnotationConfigApplicationContext()
这里主要是三个大方法:
this():初始化Spring的相关组件
this.register(annotatedClasses):把我们的配置类注册到IOC
this.refresh():这是个很重要很重要很重的方法!!!重要的事说三遍,后面会细说
我们先看 this()方法
初始化了一个读取器reader 和 一个扫描器scanner。然后:
调用静态方法 AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
往容器里注入Spring自带的注解相关的组件(一共是6个),如下:
this()方法大致就这样,接下来我们来看看 this.register(annotatedClasses)方法
可以看出,我们的配置类可以传入多个,然后循环注册
继续往下,进入registerBean()
可以看出,它把我们的配置类封装成了 beanDefinitionHolder
继续往下,进入BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
继续往下,进入registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
果断选择 DefaultListableBeanFactory
通过上下文断点+分析,程序最后走的是这段方法,即成功把我们的配置类加入到beanDefinitionMap和beanDefinitionNames中去
前方高能 refresh()方法
一共是12个大方法:本文只做与IOC相关的介绍
我们关键看 this.invokeBeanFactoryPostProcessors(beanFactory);
继续往下:
看源码看关键流程 继续往下:
Spring前面循环了所有的 BeanDefinition (容器自带的+自己定义的)
然后把自定义的配置类抽离出来,放入 Set<BeanDefinitionHolder> candidates中
然后调用 ConfigurationClassParser解析器去解析自定义的配置 candidates
继续往下:
显然是进入这里,不做过多解释
继续往下:
判断自定义的配置类 有没有 加ComponentScans注解
如果有加
继续往下:
先是得到路径集合basePackages,然后根据excludeFilter进行过滤
调用扫描器的doScan方法进行扫描
继续往下:
我们发现其实是一直在进行循环递归处理,直到basePackages循环完
解析器解析完了之后,得到一个被解析过的 Set<BeanDefinitionHolder> candidates
调用 this.reader.loadBeanDefinitions(configClasses); 把配置类中与之关联的bean信息注册到容器中去
继续:
分为了四块
1.import引入的配置类
2.内部的包含bean注解的方法
3.importedResources引入的配置
4.Registrars引入的配置
下面就没啥好看的了,一直在往容器里put就完事
总结
Spring的代码算是比较复杂的,引入了大量的组件,以及设计模式,层层嵌套。
当然对我们的提升也是有帮助的,学源码学思想。
下一篇是计划出AOP的博客
后面有时间的话,尽量出一些Spring组件的相关文章,以及自己实现一套IOC以及AOP
热爱可抵岁月漫长,大家相互学习,谢谢。