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学习笔记之启动的主要内容,如果未能解决你的问题,请参考以下文章
SpringBoot 学习笔记 -- [spring Boot配置文件之YAML格式, springBoot自动配置浅入,springboot集成JDBC]