美文网首页
2 ApplicationContext的创建

2 ApplicationContext的创建

作者: zacone | 来源:发表于2019-01-08 22:51 被阅读0次

创建ApplicationContext

public ConfigurableApplicationContext run(String... args) {
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        ConfigurableApplicationContext context = null;
        Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
        configureHeadlessProperty();
        SpringApplicationRunListeners listeners = getRunListeners(args);
        listeners.starting();
        try {
            ApplicationArguments applicationArguments = new DefaultApplicationArguments(
                    args);
            ConfigurableEnvironment environment = prepareEnvironment(listeners,
                    applicationArguments);
            configureIgnoreBeanInfo(environment);
            Banner printedBanner = printBanner(environment);
            context = createApplicationContext();
            exceptionReporters = getSpringFactoriesInstances(
                    SpringBootExceptionReporter.class,
                    new Class[] { ConfigurableApplicationContext.class }, context);
            prepareContext(context, environment, listeners, applicationArguments,
                    printedBanner);
            refreshContext(context);
            afterRefresh(context, applicationArguments);
            stopWatch.stop();
            if (this.logStartupInfo) {
                new StartupInfoLogger(this.mainApplicationClass)
                        .logStarted(getApplicationLog(), stopWatch);
            }
            listeners.started(context);
            callRunners(context, applicationArguments);
        }
        catch (Throwable ex) {
            handleRunFailure(context, ex, exceptionReporters, listeners);
            throw new IllegalStateException(ex);
        }

        try {
            listeners.running(context);
        }
        catch (Throwable ex) {
            handleRunFailure(context, ex, exceptionReporters, null);
            throw new IllegalStateException(ex);
        }
        return context;
    }

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

spring-boot会根据推断的应用类型实例化不同的ApplicationContext,比如servlet应用会实例化org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext,reactive应用会实例化org.springframework.boot.web.reactive.context.AnnotationConfigReactiveWebServerApplicationContext,它们都实现了ConfigurableApplicationContext接口。

刷新applicationContext

private void refreshContext(ConfigurableApplicationContext context) {
        refresh(context);
        if (this.registerShutdownHook) {
            try {
                context.registerShutdownHook();
            }
            catch (AccessControlException ex) {
                // Not allowed in some environments.
            }
        }
    }

        protected void refresh(ApplicationContext applicationContext) {
        Assert.isInstanceOf(AbstractApplicationContext.class, applicationContext);
        ((AbstractApplicationContext) applicationContext).refresh();
    }

AbstractApplicationContext实现了ConfigurableApplicationContext接口,而ConfigurableApplicationContext接口继承自ApplicationContext,所以ApplicationContext能被强制转换成AbstractApplicationContext
而refresh方法会在哪个类中被调用取决于创建ApplicationContext时的应用环境,若是servlet应用,会调用ServletWebServerApplicationContext的refresh方法;是reactive应用,则会调用ReactiveWebServerApplicationContext的refresh方法。
它们的refresh方法又会调用共有的父类GenericReactiveWebApplicationContext的refresh方法,从而进入spring-framework的刷新流程。

相关文章

网友评论

      本文标题:2 ApplicationContext的创建

      本文链接:https://www.haomeiwen.com/subject/uklirqtx.html