这里new了一个ClassPathXmlApplicationContext
对象,这其实是最简单的创建IOC容器的方法,我们点进去。
这是它的构造方法,它重载了其他构造方法,点this,可以看到:
在这个方法中,我们可以看到他调用了一个refresh()
刷新的方法,这个刷新就是IOC容器的刷新开启方法,我们再点进去。
类:AbstractApplicationContext
可以一次正常的流程,他一共调用了12个方法来启动IOC容器。
this.prepareRefresh();
prepareRefresh()
方法主要的作用就是在容器刷新前做准备工作:
earlyApplicationListnenrs
、earlyApplicationEvents
。obtainFreshBeanFactory();
obtainFreshBeanFactory();
方法的主要作用是创建一个DefaultListableBeanFactory工厂,给bean工厂设置一个属性,加载配置文件信息,封装bean定义信息。包扫描也是扫描到这个包下面的bean,然后封装成bean定义信息,并设置到DefaultListableBeanFactory的成员属性中。
DefaultListableBeanFactory
allowBeanDefinitionOverriding
、allowCircularReferences
。BeanDefinitionReader读取器
,将配置文件转化为输入流对象,通过SAX解析XML文件中的默认标签及自定义标签内容,封装成BeanDefinition
(也就是Bean的定义信息),注册到DefaultListableBeanFactory的beanDefinitionMap
的属性中。prepareBeanFactory(beanFactory);
prepareBeanFactory(beanFactory);
的主要作用是设置bean工厂的一些属性,如添加一些BeanPostProcessor增强器。
environment
、systemProperties
等postProcessBeanFactory(beanFactory);
postProcessBeanFactory(beanFactory);
它是一个模板方法,主要是为了留给子类扩展实现。
invokeBeanFactoryPostProcessors(beanFactory);
invokeBeanFactoryPostProcessors(beanFactory);
方法的主要作用是执行BeanFactoryPostProcessor
的后置处理器的postProcessBeanFactory()
增强方法。
BeanDefinitionRegistryPostProcessoes
。BeanDefinitionRegistryPostProcessoes
。BeanDefinitionRegistryPostProcessoes
。BeanFactoryPostProcessor
。BeanFactoryPostProcessor
。BeanFactoryPostProcessor
。registerBeanPostProcessors(beanFactory);
registerBeanPostProcessors(beanFactory);
方法的主要作用是注册BeanPostProcessor后置增强器,这里只是注册,真正执行是在初始化阶段的前后执行。
BeanPostProcessor
。BeanPostProcessor
。BeanPostProcessor
。initMessageSource();
initMessageSource();
方法的主要作用是初始化MessageSource
,国际化处理。
initApplicationEventMulticaster();
initApplicationEventMulticaster();
方法的主要作用是初始化应用事件多播器。
applicationEventMulticaster
。SimpleApplicationEventMulticaster
,并注册到IOC容器中。onRefresh();
onRefresh();
方法也是一个模板方法,留给子类扩展实现。
registerListeners();
registerListeners();
方法的主要作用是注册一些监听器。
applicationEventMulticaster事件多播器
注册一些列的监听器finishBeanFactoryInitialization(beanFactory);
finishBeanFactoryInitialization(beanFactory);
最重要的一个方法,主要是完成完成非懒加载的单例bean对象的实例化,包括反射创建bean对象、属性填充、循环依赖处理、bean的初始化等操作。
BeanDefinition
定义信息。BeanNameWare的setBeanName方法
、BeanFactoryAware的setBeanFactory方法
等。BeanPostProcessor
的后置处理器的postProcessBeforeInitialization()
方法的前置增强方法。InitializingBean的afterPropertiesSet()
方法。finishRefresh();
finishRefresh();
方法的主要作用是容器刷新完成后的一些处理工作。
第一步 首先会执行一些容器刷新前的准备工作,比如设置容器失效时间、一些状态标志位等。
第二步 创建容器对象,其实就是实例化DefaultListableBeanFactory对象,这一步包含了bean定义信息的解析,解析后的属性都封装到了DefaultListableBeanFactory
的成员属性中。
第三步 准备bean工厂,实际上就是设置beanFactory的一些属性
第四步 Spring提供了postProcessBeanFactory()
方法给我们去扩展,例如我们可以注册一些特殊的BeanPostProcessor后置处理器等操作
第五步 执行BeanFactoryPostProcessor后置处理器的postProcessBeanFactory()
增强方法,使用三个不同的集合分别存放实现了PriorityOrdered接口
、Ordered接口
、普通的BeanFactoryPostProcessor
,经过排序后,执行这个后置处理器的回调方法postProcessBeanFactory()
第六步 注册BeanPostProcessor后置处理器。这里不会执行 BeanPostProcessor对应的增强方法。同样的,使用三个不同的集合分别存放实现了PriorityOrdered接口
、Ordered接口
、普通的BeanFactoryPostProcessor
。依次调用beanFactory.addBeanPostProcessor(postProcessor)
方法往bean工厂中添加BeanPostProcess。
第七步 为上下文初始化MessageSource
,即国际化处理。
第八步 初始化事件多播器,即ApplicationEventMulticaster
,为后面的事件发布-监听做准备。
第九步 提供一个模板方法onRefresh(),留给子类初始化其他的bean。
第十步 注册事件监听器。
第十一步 也是最关键的一步,这里会实例化剩下的非懒加载的单例bean,Bean的生命周期也是从这里开始。
具体一点就是说,这里会获取到之前解析的所有bean名称集合,挨个调用getBean(beanName)
方法,然后经历doGetBean()
、createBean()
、doCreateBean()
创建bean的流程。接着会通过反射创建出我们的bean实例对象,然后进行populateBean()
属性填充。属性填充完成后,会执行bean的初始化。初始化bean的主要执行Awre
接口方法、执行初始化方法、回调BeanPostProcessor后置增强器的方法等。、
第十二步 完成上下文的刷新工作,如清除一些缓存、发布容器刷新的完成的事件等。
通过new ClassPathXMLApplicationContext
传入Spring的配置文件,创建出一个IOC容器。
配置文件:spring-config.xml
目前值配置了一个bean对象,指定了它的初始化方法以及销毁方法的方法名。还指定了为这个name属性赋值为“zhangsan”;
然后来看看我们写的Student类,实现了BeanFactory
接口、ApplicationContextAware
接口、InitializingBean
、DisposableBean
接口。
并且也重写了对应的setApplicationContext()
、setBeanFactory()
、afterPropertiesSet()
、dsetroy()
方法。
然后再创建ClassPathXMLApplicationContext的代码上打上断点,然后执行。
首先,会进入ClassPathXmlApplicationContext
的构造方法。
它调用了一个重载的构造方法,继续进入。可以看到会继续往下执行refresh()
它是IOC容器的启动的核心方法。
继续往下执行,会进入refresh()方法,正常执行会执行第一步,prepareRefresh()
,也就是进入容器刷新前的准备工作。
可以看到,这个方法实际上是设置了容器的启动时间以及一些状态标志位。
并且设置了初始化占位符属性源,以及获取到EnvironMent对象,并且验证重要的属性是否都放入到了环境中。
并且还判断了刷新前应用程序监听器集合是否为空。
如果不为空,则清空集合。
如果为空,则把监听器加入到集合中。
继续往下执行,第一个方法执行完毕。
接下来继续执行第二个方法:obtionFreshBeanFactory();
,返回值用ConfigurableListableBeanFactory
对象接收。它主要工作是创建容器,并进行XML文件读取。
继续往下执行,我们进入obtainFreshBeanFactory()
方法,接着进入refreshBeanFactory()
方法,接着继续进入createListableBeanFactory()
方法
可以看到,直接new了一个DefaultListableBeanFactory
的bean工厂。
bean工厂创建完之后,设置了工厂的序列号ID,以及定制化Bean工厂。
第一个是否允许覆盖同名的不同定义的bean对象。
第二个是是否允许循环依赖。
接着执行loadBeanDefinitions()
,这就是解析XML配置文件,加载Bean定义信息。接着继续往下执行
进入loadBeanDefinitions()
。初始化了一个XMLBeanDefinitionReader 定义信息的读取器,然后设置了一些属性。
然后进入loadBeanDefinitions()
方法,继续执行,可以看到configLocations也就是我们传入的XML配置文件的路径,然后通过loadBeanDfinitions()传入路径,进行加载,然后继续进入
这里是循环获取的,因为我们的路径可以传入多个,所以需要循环处理。
信息获取完后继续执行,然后再doLoadBeanDefinitions()
中加载bean的定义信息。
经过doLoadDocument()
方法之后,我们的XML配置文件就转换为document文档对象。然后我们就可以从文档对象中解析、注册bean的定义信息。
经过otbainFreshBeanFactory()
方法后,我们xml中bean的定义信息已被读取,并且被解析封装到了我们bean工厂中对应的成员变量中,我们通过beanFactory看到被解析出的所有信息。
第二个方法执行完毕,接着继续往下走,开始执行第三个方法:
prepareBeanFactory()
;
我们进入这个方法,可以看到实际上就是设置了一些属性而已。
比如bean的类加载器、bean的表达式解析器、属性编译器,并且添加了一些后置处理器,以及忽略了一些接口的自动装配依赖等。
接下来继续往下走,执行第四个方法:postProcessBeanFactory()
,这里是空的方法,主要是为了给子类去扩展的处理。
从注释中可以看到,执行到这里的时候,所有bean的定义信息已经加载完成,但是暂时还没bean被实例化,它允许我们注册特殊的后置处理器,
接下来执行第五个方法:invokeBeanFactoryPostProcessors()
方法。也就是执行BeanFactoryPostProcessors后置处理器的postProcessBeanFactory()增强方法。
我们进入这个方法,继续进入。
在这个方法中可以看到,分别用三个集合存放了实现了接口的后置处理器。
然后挨个通过isTypeMatch()
判断他们依次存入的是哪个集合中
存放好之后,然后排序,再进入invokeBeanFactoryPostProcessors()
方法,这个方法其实就是循环所有的后置处理器,然后回调postProcessBeanFactory()
方法
这就是第五个方法,主要是围绕后置处理器来进行操作。
然后接着往下执行,进入第六个方法:registerBeanPostProcessors()
,主要是注册bean的后置处理器BeanPostProcess
, 这里还不好执行后置处理器对应的增强方法。真正调用时在bean的初初始化之前、初始化之后。进入这个方法
很长一大段:
它的处理过程与BeanFactoryPostProcessors
类似,也是通过三个集合分别存放不同的后置处理器,然后经过排序,最后调用registerBeanPostProcess()
,这里会调用beanFactory的addBeanPostProcessor()
把这个后置处理器添加到我们bean工厂中。也就是完成了后置处理器的注册功能。
接着继续往下走,第七个方法:initMessageSource()
,为上下文初始化MessageSource,即不同语言的消息体。
我们进入这个方法。
首先会获取到当前的bean工厂,然后判断bean工厂中是否存在id为messageSource的bean。
如果存在的话,则直接获取到
如果不存在的话,则会新建一个DelegatingMessageSource,作为bean,并且id是messageSource,然后注册到bean工厂中。
接下来执行第八个方法:initApplicationEventMulticaster()
,初始化事件多播器
它的处理过程与MessageSource()
类似,
首先判断bean工厂中是否有ID为ApplicationEventMulticaster
的bean。如果有,则直接用getBean()
来获取。
如果不存在的话,则会new一个SimpleApplicationEventMutilcaster事件多播器,并注入到bean工厂中。
接着继续往下点,执行第九个方法onRefersh()
,这也是一个模板方法,留给子类初始化其他的bean。从注释上看,他允许我们执行一些特殊bean的初始化,在单例bean对象初始化之前。
接着继续执行第十个方法:registerListeners()
,注册监听器
首先,它这里会获取到硬编码方式注册的ApplicationListener,然后把他添加到事件多播器中。
其次会从bean工厂中找出所有实现了ApplicationListener接口的bean,然后循环添加到事件多播器中。
最后,它会判断如果早期应用发布事件,它会发布早期的事件到响应的监听器中, 并将earlyApplicationEvents早期事件置空。
仔细看,它发布事件就是调用我们前面初始化好的ApplicationEventMutilcaster
,然后调用它的mutilcastEvent()
发布事件。
然后执行第十一个方法finishBeanFactoryInitialization(beanFactory)
他是refresh()
中最重要的一个方法,实例化所有剩下的非懒加载的单例Bean。
其他都是一些中规中矩的代码,最后一行尤为重要:实例化所有剩余的非懒加载单例bean。
我们继续进入preInstantiateSingletons()
,(可以看到增强for循环的beanNames只有一个Students),然后它会循环所有的beanName
,挨个调用getBean()
方法
这里会执行getBean(beanNane)
,然后进入
会执行doGetBean()
这里会执行createBean()
,创建bean对象,进入这个方法。
我们继续执行:
bean实例化完成后会进行属性填充,对bean的各个属性值进行注入,可以存在其他依赖bean的属性,则会递归初始依赖的bean。
我们进入,首先会执行Aware接口的invokeAwareMethods()
方法。这是因为Student实现了BeanFactoryAware接口,所有这里它会回调这个类的setBeanFactory()
方法。
Aware接口执行完后,会执行我们BeanPostProcessor后置处理器的前置处理方法,也就是回调postProcessBeforeInitialization()
,点击进入。
前置回调方法处理完后,会调用invokeInitMethods()
执行初始化方法,我们进入。
首先会判断这个bean是否试下了InitializingBean
接口。
我们的Student是实现了InitializingBean的,所有它会回调我们的afterPropertiesSet()
方法,执行一些初始化工作
初始化方法完成后,通过下面这个方法可以执行后置处理器的后置处理方法。点击方法内部,他是循环所有的BeanPostProcessor后置增强器,然后挨个调用后置增强方法。
初始化方法完成后,这个bean就已经创建成功了,接着它会存入到我们的缓存中。
这就是第十一个方法,实例化所有的非懒加载单例Bean,内容很多,但也很重要。
最后第十二个方法,finishRefresh()
,它是完成上下文的刷新工作。
主要就是清除一些缓存,初始化生命周期处理器,以及发布容器刷新完成的一些事件等。
通过这些步骤,一个完整的bean对象就被创建了出来,也是IOC容器的启动过程