SpringApplication启动流程六

2023-05-01  本文已影响0人  程序员札记

初始化基本流程

SpringApplication的prepareEnvironment准备环境

private ConfigurableEnvironment prepareEnvironment(SpringApplicationRunListeners listeners,
            ApplicationArguments applicationArguments) {
        // Create and configure the environment
        ConfigurableEnvironment environment = getOrCreateEnvironment();//获取环境
        configureEnvironment(environment, applicationArguments.getSourceArgs());
        ConfigurationPropertySources.attach(environment);//ConfigurationPropertySources附加到环境一次
        listeners.environmentPrepared(environment);//广播环境准备好的事件
        bindToSpringApplication(environment);//绑定到SpringApplication
        if (!this.isCustomEnvironment) {
            environment = new EnvironmentConverter(getClassLoader()).convertEnvironmentIfNecessary(environment,
                    deduceEnvironmentClass());//推断环境,如果不是这个类型,要进行切换
        }
        ConfigurationPropertySources.attach(environment);//又附加一次,主要是为了放最前面
        return environment;
    }

SpringApplication的getOrCreateEnvironment创建环境
根据前面的webApplicationType判断要创建哪种环境。

    private ConfigurableEnvironment getOrCreateEnvironment() {
        if (this.environment != null) {
            return this.environment;
        }
        switch (this.webApplicationType) {
        case SERVLET:
            return new StandardServletEnvironment();
        case REACTIVE:
            return new StandardReactiveWebEnvironment();
        default:
            return new StandardEnvironment();
        }
    }

configureEnvironment配置环境
这里主要是配置了很多的类型转换器和格式转换器,另外两个跟换进属性相关

    protected void configureEnvironment(ConfigurableEnvironment environment, String[] args) {
        if (this.addConversionService) {
            ConversionService conversionService = ApplicationConversionService.getSharedInstance();//配置转换器
            environment.setConversionService((ConfigurableConversionService) conversionService);//设置到环境中去
        }
        configurePropertySources(environment, args);//配置默认属性
        configureProfiles(environment, args);//配置代码添加的环境
    }

ApplicationConversionService的getSharedInstance配置转换器
这个里面有配置很多转换器,我就不多讲了,自己看就行了。


image.png image.png

其他剩下的暂时不讲,因为比较复杂,很多都是一些属性的配置,比如会获取你的spring.profiles.active信息,而且是ConfigFileApplicationListener收到环境准备好的事件后做的事,当然还有其他的一些配置信息,我们还是先把主线弄明白再搞细节,不过这里配置完成会进行广播,这次的事件是ApplicationEnvironmentPreparedEvent:

image.png

SpringApplication的printBanner打印banner
内部支持 "gif", "jpg", "png","txt":


image.png

默认把资源放到resources下,名字为banner.xxx就可以了,自己可以去试试:


image.png

我们经常看到的默认的在这里面:


image.png

createApplicationContext创建上下文
根据类型创建对应的上下文对象,默认全是注解

    protected ConfigurableApplicationContext createApplicationContext() {
        Class<?> contextClass = this.applicationContextClass;
        if (contextClass == null) {
            try {
                    switch (this.webApplicationType) {
                case SERVLET://AnnotationConfigServletWebServerApplicationContext
                    contextClass = Class.forName(DEFAULT_SERVLET_WEB_CONTEXT_CLASS);
                    break;
                case REACTIVE://AnnotationConfigReactiveWebServerApplicationContext
                    contextClass = Class.forName(DEFAULT_REACTIVE_WEB_CONTEXT_CLASS);
                    break;
                default://AnnotationConfigApplicationContext
                    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);
    }

image.png

准备环境这里比较复杂,准备完了就是spring的核心refresh了。

上一篇下一篇

猜你喜欢

热点阅读