Spring IOC的初始化流程
1、项目从 ApplicationContext app = new ClassPathXmlApplicationContext(“applicationContext.xml”);
2、找到工厂实现类【ClassPathXmlApplicationContext】中对应的构造方法,执行ioc容器初始化:
如下:
*使用给定的父类创建一个新的ClassPathXmlApplicationContext,
从给定的XML文件中加载定义。
* @param configLocations资源位置数组
是否自动刷新上下文,
加载所有bean定义并创建所有的单例。
*或者,在进一步配置上下文之后手动调用refresh。
* @param父上下文
如果上下文创建失败,@抛出BeansException
* @see # refresh () 
<ignore_js_op>

3、找到工厂抽象父类【AbstractApplicationContext】中的【refresh】方法:
3.1.该方法实现解析xml配置文件内容,封装成BeanDefinition对象,注册到BeanFactory中
3.2.该方法实现一些基础组件的注册:bean后置处理器组件、监听器组件、国际化资源组件
3.3.该方法实现bean对象的真正实例化。细节:初始化全部【singleton】单例对象,标记为【lazy-init】延迟加载的对象除外
流程小结:
1、在应用程序中初始化ioc容器的入口是 ClassPathXmlApplicationContext工厂实现类
2、在ClassPathXmlApplicationContext的构造方法中调用了refresh方法
2.1.refresh不仅仅是初始化ioc容器,如果已经有ioc容器了就更新容器
2.2.spring框架在处理过程中会考虑先释放已经存在的ioc容器。再重新创建一个ioc容器
3、spring框架允许在一个应用中有多个ioc容器,他们之间是父子关系。ssm框架就有两个ioc容器:
3.1通过ContextLoaderListener监听器,加载spring配置文件,创建的父容器
3.2通过DispatcherServlet前端控制器加载springmvc主配置文件创建的子容器
4、spring框架在创建ioc容器时,主体流程:
4.1设置容器的初始化状态,如:容器的启动时间,容器的激活状态
4.2解析bean.xml配置文件,将配置文件中的信息解析封装程BeanDefinition对象
4.3将BeanDefinition对象注册到BeanFactory容器中。此时还没有真正创建bean对象,只是解析封装xml配置文件的内容
4.4设置一些公共资源。如:bean的后置处理器,类加载器,监听器,国际化资源等
4.5根据BeanDefinition对象真正创建bean对象, 此时创建的全是单例【singleton】,并且不是延迟加载【lazy-init】的对象
4.6最后一步广播事件,进行善后处理
[size=1em]CustomerController
[Java] 纯文本查看 复制代码
| 
 01 
02 
03 
04 
05 
06 
07 
08 
09 
10 
11 
12 
13 
 | 
/** * 客户表现层 */public class CustomerController {    public static void main(String[] args) {        // 1.加载spring 配置文件,初始化创建ioc容器        ApplicationContext context = new ClassPathXmlApplicationContext("classpath:bean.xml");        // 2.从ioc容器获取service        CustomerService customerService = (CustomerService)context.getBean("customerService");        // 3.保存客户操作        customerService.saveCustomer();    }} | 
[size=1em]ClassPathXmlApplicationContext
[size=1em]
[Java] 纯文本查看 复制代码
| 
 01 
02 
03 
04 
05 
06 
07 
08 
09 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
28 
29 
30 
31 
32 
33 
34 
 | 
public class ClassPathXmlApplicationContext extends AbstractXmlApplicationContext {        // 资源配置文件成员变量,是一个数组,支持多个spring的配置文件     @Nullable    private Resource[] configResources;     // 默认构造方法    public ClassPathXmlApplicationContext() {    }    // 如果已经存在一个ioc容器,可以在构造的时候设置【父】容器    public ClassPathXmlApplicationContext(ApplicationContext parent) {        super(parent);    }     // 【重点跟踪】根据xxx.xml配置文件,创建ioc容器    public ClassPathXmlApplicationContext(String configLocation) throws BeansException {        this(new String[]{configLocation}, true, (ApplicationContext)null);}..........................................    /**    *【重点跟踪】方法说明:    *    根据xml文件的定义,以及父容器,创建一个新的ClassPathXmlApplicationContext    *    *参数说明:    *    configLocations:xml配置文件数组    *    refresh:是否要重新创建ioc容器。加载全部bean的定义和创建所有的单例对象    *    parent:父容器    */    public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, @Nullable ApplicationContext parent) throws BeansException {        super(parent);// 设置父容器       // 根据提供的路径,处理成配置文件数组(以分号、逗号、空格、tab、换行符分割)        this.setConfigLocations(configLocations);        if (refresh) {            this.refresh();// 【核心方法】:该方法表示初始化(或者重建)ioc容器。即可以把原来的ApplicationContext销毁,重新执行初始化创建        }    }..........................................} | 
[size=1em]
[size=1em]AbstractApplicationContext
[AppleScript] 纯文本查看 复制代码
| 
 01 
02 
03 
04 
05 
06 
07 
08 
09 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
28 
29 
30 
31 
32 
33 
34 
35 
36 
37 
38 
39 
40 
41 
42 
43 
44 
45 
46 
47 
48 
49 
50 
51 
52 
53 
54 
55 
56 
57 
58 
59 
60 
61 
62 
63 
64 
65 
66 
67 
68 
 | 
public abstract class AbstractApplicationContext extends DefaultResourceLoader implements ConfigurableApplicationContext { ..........................................     /**     *【重点跟踪】方法说明:     *    【核心方法】:该方法表示初始化(或者重建)ioc容器。即可以把原来的ApplicationContext销毁,重新执行初始化创建      */    public void refresh() throws BeansException, IllegalStateException {       // 创建ioc容器,同步加锁,保障线程安全       synchronized (this.startupShutdownMonitor) {            // 准备工作:记录容器启动的时间,和状态标记            prepareRefresh();            // 关键步骤:                //    1.根据配置文件中配置内容,解析成一个个Bean实例(BeanDefinition)             //    2.将一个个Bean实例,注册到BeanFactory中                // 3.细节:这里的Bean实例仅仅是描述Bean的相关信息,此时还没有真正创建对应的bean对象            ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();            // 设置BeanFactory:                // 1.设置类加载器                // 2.设置BeanPostProcessor(bean后置处理器)                // 3.注册特殊的bean(框架内部使用的bean)            prepareBeanFactory(beanFactory);            try {                // 设置BeanFactoryPostProcessor                postProcessBeanFactory(beanFactory);                // 调用BeanFactoryPostProcessor各个实现类的 postProcessBeanFactory(factory) 方法                 // 
Bean实现BeanFactoryPostProcessor接口,增强该Bean的功能                invokeBeanFactoryPostProcessors(beanFactory);                // 注册BeanPostProcessor的实现类:                  // 1.该接口有两个方法:                  //      postProcessBeforeInitialization(),在init-method属性指定的方法前调用                  //      postProcessAfterInitialization(),在init-method属性指定的方法后调用                registerBeanPostProcessors(beanFactory);                // 初始化国际化支持的资源文件                initMessageSource();                // 初始化ApplicationContext事件广播器                initApplicationEventMulticaster();                // 模板方法:用于特殊bean的初始化,默认是空实现(在api中如果预留了一些方法实现是空,表示该方法是留给子类自我实现。那么这些方法称为:钩子方法)                onRefresh();                // 注册事件监听器:监听器需要实现ApplicationListener接口                registerListeners();                  // 【重点步骤】:                  // 1.实例化所有单例bean对象,除开延迟加载的bean                  // <bean id="customerDao" class="com.itheima.dao.impl.CustomerDaoImpl" lazy-init="false" scope="singleton"/>                finishBeanFactoryInitialization(beanFactory);                // 【最后一步】:                  // 1.发布广播事件。ApplicationContext初始化完成                finishRefresh();            }catch (BeansException ex) {                if (logger.isWarnEnabled()) {                    logger.warn("Exception encountered during context initialization - " +                            "cancelling refresh attempt: " + ex);                }                 // 如果发生异常,需要销毁已经创建的singleton对象                destroyBeans();                  // 将active状态设置为false                cancelRefresh(ex);                // Propagate exception to caller.                throw ex;            }finally {                // Reset common introspection caches in Spring's core, since we                // might not ever need metadata for singleton beans anymore...                resetCommonCaches();            }        }    }      ..........................................   }更多技术资讯可关注:itheimaGZ获取(公冢号) | 
来源:https://www.cnblogs.com/zhuxiaopijingjing/p/12326228.html