趁着假期 && 疫情, 沉淀一下
废话不多说,直奔正题。
Spring的核心,即IOC和AOP,本篇文章其实就是来分析下 Spring 的 IOC 容器,IOC又叫控制反转,把对象以Bean的形式交给IOC去管理,由Spring去管理对象的生命周期,使得Bean与Bean之间的松耦合。
Spring的注解启动类
进入 AnnotationConfigApplicationContext()
this():初始化Spring的相关组件 this.register(annotatedClasses):把我们的配置类注册到IOC this.refresh():这是个很重要很重要很重的方法!!!重要的事说三遍,后面会细说 复制代码
我们先看 this()方法
调用静态方法 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
热爱可抵岁月漫长,大家相互学习,谢谢。