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当中了。