springboot启动流程(五)建立ApplicationContext

全部文章

http://www.javashuo.com/article/p-uvudtich-bm.htmlhtml

 

正文

springboot在启动过程当中将会根据当前应用的类型建立对应的ApplicationContext。本文内容较短,承上启下,将不会涉及太多具体的内容,主要在于为后续的ioc内容构建一个ApplicationContext实例。react

咱们简单回顾一下,在第二篇文章介绍SpringApplication的run方法web

public ConfigurableApplicationContext run(String... args) {
    // 声明一个Context容器
    ConfigurableApplicationContext context = null;
    // 获取监听器
    SpringApplicationRunListeners listeners = getRunListeners(args);
    // 调用监听器的启动
    listeners.starting();

    try {
        // 建立并配置Environment(这个过程会加载application配置文件)
        ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);
        // 根据应用类型建立对应的Context容器
        context = createApplicationContext();

        // 刷新Context容器以前的准备
        prepareContext(context, environment, listeners, applicationArguments, printedBanner);
        // 刷新Context容器
        refreshContext(context);
        // 刷新Context容器以后处理
        afterRefresh(context, applicationArguments);

        // Context容器refresh完毕发布
        listeners.started(context);

        // 触发Context容器refresh完之后的执行
        callRunners(context, applicationArguments);
    } catch (Throwable ex) {}

    try {
        // Context启动完毕,Runner运行完毕发布
        listeners.running(context);
    } catch (Throwable ex) {}

    return context;
}

逻辑步骤中,建立Environment以后,刷新ApplicationContext以前,咱们还须要作的一件事就是建立ApplicationContext实例,也就是createApplicationContext方法spring

 

咱们跟进createApplicationContextspringboot

public static final String DEFAULT_SERVLET_WEB_CONTEXT_CLASS = "org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext";

public static final String DEFAULT_REACTIVE_WEB_CONTEXT_CLASS = "org.springframework.boot.web.reactive.context.AnnotationConfigReactiveWebServerApplicationContext";

public static final String DEFAULT_CONTEXT_CLASS = "org.springframework.context.annotation.AnnotationConfigApplicationContext";

protected ConfigurableApplicationContext createApplicationContext() {
    // 先判断有没有指定的实现类
    Class<?> contextClass = this.applicationContextClass;
    // 若是没有,则根据应用类型选择
    if (contextClass == null) {
        try {
            switch (this.webApplicationType) {
            case SERVLET: 
                contextClass = Class.forName(DEFAULT_SERVLET_WEB_CONTEXT_CLASS);
                break;
            case REACTIVE:
                contextClass = Class.forName(DEFAULT_REACTIVE_WEB_CONTEXT_CLASS);
                break;
            default:
                contextClass = Class.forName(DEFAULT_CONTEXT_CLASS);
            }
        }
        catch (ClassNotFoundException ex) {
            throw new IllegalStateException(
                    "Unable create a default ApplicationContext, " + "please specify an ApplicationContextClass",
                    ex);
        }
    }
    // 经过反射获取对应类的实例
    return (ConfigurableApplicationContext) BeanUtils.instantiateClass(contextClass);
}

该方法的逻辑较为简单,走两个分支app

1)自定义ApplicationContext的实现类this

2)根据当前应用的类型webApplicationType来匹配对应的ApplicationContext,是servlet、reactive或者非web应用spa

 

总结

建立ApplicationContext的实例对象较为简单,就是选择实现类,反射获取类的实例对象。至于实现类是本身设置的,仍是经过当前应用类型匹配的由开发人员去选择,不过默认状况下都是由类型去推断出来的。code

本文虽短,可是后续的文章也基本都是围绕着本文构建的ApplicationContext,这说明spring的核心也基本都包含在这个ApplicationContext当中了。htm

相关文章
相关标签/搜索