zoukankan      html  css  js  c++  java
  • springboot启动流程(五)创建ApplicationContext

    所有文章

    https://www.cnblogs.com/lay2017/p/11478237.html

    正文

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

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

    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方法

    我们跟进createApplicationContext

    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);
    }

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

    1)自定义ApplicationContext的实现类

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

    总结

    创建ApplicationContext的实例对象较为简单,就是选择实现类,反射获取类的实例对象。至于实现类是自己设置的,还是通过当前应用类型匹配的由开发人员去选择,不过默认情况下都是由类型去推断出来的。

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

  • 相关阅读:
    Java之final关键字
    Java之代码块
    Java之单例设计模式
    Java之数组
    python基础知识第九篇(函数)
    css--属性
    css-选择器
    css--引入css的3种方法
    html--多选
    python-列表--处理
  • 原文地址:https://www.cnblogs.com/lay2017/p/11486497.html
Copyright © 2011-2022 走看看