今天,以ClassPathXmlApplicationCont"/>

Spring学习笔记之启动

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring学习笔记之启动相关的知识,希望对你有一定的参考价值。

技术分享

今天,以ClassPathXmlApplicationContext为例来看一下,Spring启动的时候都做了什么

技术分享

技术分享

重点看refresh()方法

refresh()方法是在AbstractApplicationContext类中定义的

ClassPathXmlApplicationContext间接继承AbstractApplicationContext

技术分享

这里面每一行代码的注释都写得很清楚我就不废话了,一行一行往下看

第1步、准备刷新上下文(PS:就不细看了)

第2步、获取BeanFactory


技术分享

AbstractApplicationContext中的refreshBeanFactory()方法是一个抽象方法,咱们看一下具体实现。具体实现实在AbstractRefreshableApplicationContext类中。

技术分享

可以看到,如果Bean工厂存在,则销毁,然后重新创建,不存在,则新建。

技术分享

可以看到,新创建的Bean工厂是new了一个DefaultListableBeanFactory。

有了Bean工厂以后,接下来加载Bean定义。

本示例中loadBeanDefinitions()方法是在AbstractXmlApplicationContext类中定义的。

AbstractXmlApplicationContext间接继承AbstractRefreshableApplicationContext,同时,也是ClassPathXmlApplicationContext的直接父类。

技术分享

至于,它到底是怎么加载,怎么解析的,这里就不细说了,很复杂

技术分享

总之呢,到此为止,BeanFactory也获取到了,Bean定义也加载了。

接下来,回到refresh()

第3步、准备BeanFactory

技术分享

这里,对传入的BeanFactory做了一系列配置,比如,类加载器,表达式解析器,BeanPostProcessor。反正,到此为止,BeanFactory已经创建并配置完成,接下来第4步调用postProcessBeanFactory()方法,这个方法是为子类预留的,就是一个后置回调,允许子类在BeanFactory初始化之后做一些事情。

第5步、实例化并调用所有已经在BeanFactory中注册了的BeanFactoryPostProcessor

技术分享

技术分享

技术分享


这里补充一点,DefaultListableBeanFactory是实现了BeanDefinitionRegistry接口的。

技术分享

技术分享

第6步、实例化并且调用所有已经注册的BeanPostProcessor(PS:注意,是BeanPostProcessor,而不是BeanFactoryPostProcessor,BeanFactoryPostProcessor是在上一步中完成的。从这里我们也可以看出BeanFactoryPostProcessor和BeanPostProcessor的执行顺序。)

技术分享

技术分享

技术分享

这里,从Bean定义中找到所有BeanPostProcessor类型的定义然后注册他们

第7步、初始化Message Resource

第8步、初始化时间广播器

第9步、初始化子类中其它的Bean,这里为子类留了一个口子

第10步、注册监听器

第11步、实例化所有的单例的Bean(PS:就是scope=singleton的Bean)

技术分享

接下来,看看DefaultListableBeanFactory是怎么实现的

技术分享


重点看getBean()方法

技术分享

接着往下看doGetBean()

技术分享

看到有一个createBean方法

技术分享

技术分享

技术分享


前面,费了那么大的劲就是做一些校验啊之类的,最终获得了RootBeanDefinition,有了这个东西之后就可以实例化了。

在上面的createBeanInstance方法中,

(1)如果这个类不是public的话,抛异常

(2)这个Bean的定义中有工厂方法,则使用它自带的工厂方法实例化

(3)如果需要自动装配,就用构造器装配实例化

(4)如果都不是,就用普通的方式实例化,其实就是用默认的构造器实例化

技术分享

实例化之前,这里要获取实例化的策略。

那么,有哪些策略呢?

技术分享

技术分享

技术分享


这里,我们可以清楚的看到,默认的策略是Cglib

用Cglib返回的是代理对象

另外,还有一种就是普通的用默认构造方法实例化,这种返回的是真实对象。

接下来,还有最后一步

第12步、初始化LifecycleProcessor,并调用其onRefresh()方法,然后发布ContextRefreshedEvent事件


到此为止,AbstractApplicationContext的refresh()方法算是讲完了。

下面总结一下:

第1步、准备刷新

第2步、加载Bean定义,并获取BeanFactory,这里获取的是DefaultListableBeanFactory

第3步、配置BeanFactory,包括配置类加载器、配置BeanPostProcessor

第4步、调用postProcessBeanFactory()方法,这个方法是给子类预留的

第5步、实例化并调用所有注册的BeanFactoryPostProcessor

第6步、实例化并调用所有注册的BeanPostProcessor

第7步、初始化message resource

第8步、初始化事件广播器

第9步、调用onRefresh()方法,这是一个模板方法,是给子类预留的

第10步、注册监听器

第11步、完成BeanFactory的初始化,并且实例化所有的单例(scope=singleton)Bean

第12步、初始化LifecycleProcessor,并调用其onRefresh()方法,然后发布ContextRefreshedEvent事件


到此结束!!!

最后,补充一个

技术分享


本文出自 “十里稻花香” 博客,请务必保留此出处http://5880861.blog.51cto.com/5870861/1970641

以上是关于Spring学习笔记之启动的主要内容,如果未能解决你的问题,请参考以下文章

spring技术内幕读书笔记之IoC容器的学习

Spring学习系列笔记之Spring心得

Spring boot 学习笔记

SpringBoot 学习笔记 -- [spring Boot配置文件之YAML格式, springBoot自动配置浅入,springboot集成JDBC]

我的第一个spring boot程序(spring boot 学习笔记之二)

《一头扎进Spring4》学习笔记Spring ioc 之详解