SpringApplicationContext

简介(What)

在使用Spring Boot的时候,都知道通过SpringApplication.run(MyApplicaton)即可创建一个Spring应用,但是大家有没有注意这个方法的返回值呢?

    public static ConfigurableApplicationContext run(Class<?> primarySource, String... args) {
        return run(new Class<?>[] { primarySource }, args);
    }

run()方法返回了一个ConfigurableApplicationContext的实例,那么这个实例是如何被创建的呢,创建的又是哪个对象的实例呢?

目标(Target)

本文将通过源码的方式,来解决以下问题:

对象指是的Class对象实例指的是Object

原理(How)

在SpringApplication的构造方法中,有这么一行代码:

this.webApplicationType = WebApplicationType.deduceFromClasspath();

在SpringApplication的实例run()方法中,有如下的方法的调用:

context = createApplicationContext();

createApplicationContext()方法,又调用了applicationContextFactory.create()方法:

protected ConfigurableApplicationContext createApplicationContext() {
    return this.applicationContextFactory.create(this.webApplicationType);
}

applicationContextFactory成员变量定义如下:

private ApplicationContextFactory applicationContextFactory = ApplicationContextFactory.DEFAULT;

WebApplicationType

WebApplicationType枚举定义了Spring Application的类型,有NONESERVLETREACTIVE三种。

deduceFromClasspath()方法中,使用工具方法ClassUtils.isPresent(className)来判断特定的类是否存在,从而推断将要实例的应用类型:

    static WebApplicationType deduceFromClasspath() {
        if (ClassUtils.isPresent(WEBFLUX_INDICATOR_CLASS, null) && !ClassUtils.isPresent(WEBMVC_INDICATOR_CLASS, null)
                && !ClassUtils.isPresent(JERSEY_INDICATOR_CLASS, null)) {
            return WebApplicationType.REACTIVE;
        }
        for (String className : SERVLET_INDICATOR_CLASSES) {
            if (!ClassUtils.isPresent(className, null)) {
                return WebApplicationType.NONE;
            }
        }
        return WebApplicationType.SERVLET;
    }

ApplicationContextFactory.DEFAULT

ApplicationContextFactory的默认实现DEFAULT中,根据WebApplicationType的类型,创建对应的ConfigurableApplicationContext实例:

switch (webApplicationType) {
case SERVLET:
    return new AnnotationConfigServletWebServerApplicationContext();
case REACTIVE:
    return new AnnotationConfigReactiveWebServerApplicationContext();
default:
    return new AnnotationConfigApplicationContext();
}

更多ApplicationContextFactory请查看应用上下文工厂