美文网首页
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