Spring学习笔记之启动

wKiom1nYl-jD_XwmAAAnevpU4QE930.png

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

wKiom1nYmJqj4-piAAAawDSEZ4w307.png

wKioL1nYmEygSmIBAAA0VnytlHQ615.png

重点看refresh()方法post

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

ClassPathXmlApplicationContext间接继承AbstractApplicationContext3d

wKiom1nYmbDgNsVXAAFEofaJepk297.png

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

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

第2步、获取BeanFactoryblog


wKiom1nYm0WQhSkjAACSbf737qs538.png

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

wKiom1nYm_iwkz4AAACcQ4U2Q50513.png

能够看到,若是Bean工厂存在,则销毁,而后从新建立,不存在,则新建。接口

wKiom1nYnIbQOfM3AADTazx-jy0444.png

能够看到,新建立的Bean工厂是new了一个DefaultListableBeanFactory。事件

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

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

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

wKioL1nYncyiCJBUAADlQnWX4Eo104.png

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

wKiom1nYnuGTHJ7pAABUqFAjoPw886.png

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

接下来,回到refresh()

第3步、准备BeanFactory

wKiom1nYoQaRGSIgAAGSf_jilSM940.png

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

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

wKioL1nYo_fyLRYHAADdNnf55bI457.png

wKiom1nYpEXTa5UPAAEbDTDFdLE722.png

wKiom1nYpEWD9JucAAENZEdtfvc687.png


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

wKioL1nYpPeSirYsAAArPfK9pk8993.png

wKiom1nYpUXQZFAoAAF40_jdBys489.png

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

wKioL1nYqYbiTKZvAAA-V052zNw988.png

wKioL1nYqROhKqjKAAFG9bzV0WY696.png

wKiom1nYqWHiLO8jAAFC4XMVOns865.png

这里,从Bean定义中找到全部BeanPostProcessor类型的定义而后注册他们

第7步、初始化Message Resource

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

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

第10步、注册监听器

第11步、实例化全部的单例的非懒加载的Bean(PS:就是scope=singleton,而且lazy-init=false的Bean)

wKiom1nYrpvQ9mM_AAFSZAtjMFs815.png

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

wKioL1nY5W7QpmmnAAF7o1H4Hxk728.png

wKiom1nY5dXgxC1lAABdiW2UOpg907.png


这里初始化全部非懒加载的单例Bean

重点看getBean()方法

wKioL1nYs-iQE7yoAAAj0dnnmeY329.png

接着往下看doGetBean()

wKiom1nYtIqSGtl4AAETlLVK2gM832.png

看到有一个createBean方法

wKioL1nYuBmBKXmyAAE48Hzlaac182.png

wKioL1nY8a3Cq4EIAALGkN9DhNA811.png

wKiom1nYuZHQO6EgAAGusHyCZsE035.png

wKiom1nY8zHgs9aGAAIkFFKW_AY728.png

wKioL1nY8uPBJtAdAACSE6W0Uok714.png

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

在上面的createBeanInstance方法中,

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

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

(3)若是须要自动装配,就用构造器装配实例化

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

wKioL1nYu9CwCdXoAADQ7NhHuC0966.png

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

那么,有哪些策略呢?

wKiom1nYvYmjbP9aAAAkELzRTHE322.png

wKiom1nYvYnwn75EAAAycONNf5I487.png

wKioL1nYvTuCUDobAAEENUJAF3c292.png


这里,咱们能够清楚的看到,默认的策略是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,lazy-init=false)Bean

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


到此结束!!!

最后,补充两点:

第一点是onRefresh()方法

wKiom1nYwmbT7WSrAABJZofMre0376.png

第二点是,当第一次调用getBean()方法时会触发依赖注入,从上面的第11步中咱们能够看到,大部分Bean在Spring启动的时候就已经完成了依赖注入。注入是在AbstractAutowireCapableBeanFactory类的populateBean方法完成的。

第三点是,Spring对Bean的依赖关系提供了两种方式:

(1)显式方式:经过BeanDefinition中的属性和构造方法,即经过构造方法的形式将依赖的Bean传入进来

(2)自动装配(autowiring):容器会自动使用反射查找属性的类型和名称,而后基于属性的类型或者名称来自动匹配容器中管理的Bean,从而自动地完成依赖注入。

wKiom1nY7h_So14EAAECPoCv__I843.png

相关文章
相关标签/搜索