![](https://img.haomeiwen.com/i7416970/4e3b30eba066acf2.jpg)
我们都知道BeanFactory和ApplicationContext是作为Spring IOC容器的顶层接口,其实不管是用默认的ClasspathXmlApplicationContext加载xml还是使用AnnotationAplicationContext通过Java Config方式启动Spring,他们的过程其实都大同小异。本文就来分析下web环境下Spring容器的初始化。
首先启动SpringBoot项目会执行SpringApplication.run(App.class, args),进入方法内部
![](https://img.haomeiwen.com/i7416970/789ea8f56c2391cd.png)
首先我们先来看createApplicationContext方法,即进行IOC容器的创建,进入方法
![](https://img.haomeiwen.com/i7416970/64a22885cfb34dd8.png)
我们发现他会根据是否为web环境创建容器。默认的web容器是AnnotationConfigEmbeddedWebApplicationContext。接着来看初始化方法,进入refreshContext(context)方法,该方法为刷新容器的方法,一步步点进去,发现来到其父类AbstractApplicationContext的refresh()方法,着重分析一下该方法。
![](https://img.haomeiwen.com/i7416970/f290196b72f33ec1.png)
![](https://img.haomeiwen.com/i7416970/a858332ad00f5167.png)
1.首先来看prepareRefresh()方法,他主要做一些容器的准备
![](https://img.haomeiwen.com/i7416970/9d9d95edc9db9638.png)
如图,注释已经很清楚了,注意有个init方法,记得我们以前开发时配置JDBC文件位置使用placeholder就是在这里进行注册的。
2.obtainFreshBeanFactory()方法主要做的工作就是销毁之前的bean工厂并创建新的BeanFactory。
3.prepareBeanFactory(beanFactory);进行bean工厂的准备工作,主要为进行bean工厂的配置,注册一些内部bean。
4.postProcessBeanFactory(beanFactory);该方法允许子类进行beanFactory的修改。
5.invokeBeanFactoryPostProcessors(beanFactory);初始化并执行容器中所有实现了BeanFactoryPostProcessor接口的bean。
6.registerBeanPostProcessors(beanFactory);注册所有的BeanPostProcessor用于拦截bean的初始化,这是Spring给我们提供的扩展点之一。
![](https://img.haomeiwen.com/i7416970/2571be8934d5eaa4.png)
这里需要注意一下的是,BeanPostProcessor其实可以指定顺序的,由方法可知他先注册实现了PriorityOrdered接口的,再注册实现了Ordered接口的最后注册没实现接口的。
7.initMessageSource();初始化国际化所使用的MessageSource。
8.initApplicationEventMulticaster();初始化Spring的事件广播器。
9.onRefresh();留给子类去实现用于初始化特定Context所需要的Bean。
10.registerListeners();得到所有ApplicationListener并发布相应的容器事件
11.finishBeanFactoryInitialization(beanFactory);结束beanFactory的创建并初始化容器中的非lazy单例bean,所有指定延迟加载为false的bean会在此处进行初始化。默认情况下是在启动的时候进行加载所有bean。
12.finishRefresh();最后一步
![](https://img.haomeiwen.com/i7416970/912a302452ef6e0c.png)
执行相应的生命周期方法并发布容器刷新事件。
13.如果出异常进行容器的销毁。
14.最后进行相关缓存的清空。
至此Refresh方法已经全部分析完了。他是IOC容器创建的核心方法。
让我们回到SpringApplication中的run方法,执行完refreshContext(context)之后,就是发布相应SpringApplicationRunListener事件,最后返回创建的Context。
以上即为SpringIOC容器的创建过程分析
end。
网友评论