今天,以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,并且lazy-init=false的Bean)
接下来,看看DefaultListableBeanFactory是怎么实现的
这里初始化所有非懒加载的单例Bean
重点看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,lazy-init=false)Bean
第12步、初始化LifecycleProcessor,并调用其onRefresh()方法,然后发布ContextRefreshedEvent事件
到此结束!!!
最后,补充两点:
第一点是onRefresh()方法
第二点是,当第一次调用getBean()方法时会触发依赖注入,从上面的第11步中我们可以看到,大部分Bean在Spring启动的时候就已经完成了依赖注入。注入是在AbstractAutowireCapableBeanFactory类的populateBean方法完成的。
第三点是,Spring对Bean的依赖关系提供了两种方式:
(1)显式方式:通过BeanDefinition中的属性和构造方法,即通过构造方法的形式将依赖的Bean传入进来
(2)自动装配(autowiring):容器会自动使用反射查找属性的类型和名称,然后基于属性的类型或者名称来自动匹配容器中管理的Bean,从而自动地完成依赖注入。
本文转自 手不要乱摸 51CTO博客,原文链接:http://blog.51cto.com/5880861/1970641