SpringCloud Alibaba 启动

SpringCloud Alibaba 启动过程

Springboot 2.2.12版本

获取初始化类,实例化SpringApplication

 this.setInitializers(this.getSpringFactoriesInstances(ApplicationContextInitializer.class));

1、获取项目中 META-INF/spring.factories 的启动时的配置类
如果项目中添加了OpfenFeign jar包,那么这个时候会找到META-INF/spring.factories 下的参数放进缓存中,并添加org.springframework.context.ApplicationContextInitializer参数到LinkedHashMap 中返回

private <T> Collection<T> getSpringFactoriesInstances(Class<T> type, Class<?>[] parameterTypes, Object... args) {
        ClassLoader classLoader = this.getClassLoader();
        Set<String> names = new LinkedHashSet(SpringFactoriesLoader.loadFactoryNames(type, classLoader));**
       *******************
        return instances;
    }

2、实例化ApplicationContextInitializer 类
OpfenFeign 没有配置该参数
org.springframework.boot.autoconfigure.EnableAutoConfiguration=
org.springframework.cloud.openfeign.ribbon.FeignRibbonClientAutoConfiguration,
org.springframework.cloud.openfeign.FeignAutoConfiguration,
org.springframework.cloud.openfeign.encoding.FeignAcceptGzipEncodingAutoConfiguration,
org.springframework.cloud.openfeign.encoding.FeignContentGzipEncodingAutoConfiguration

  private <T> Collection<T> getSpringFactoriesInstances(Class<T> type, Class<?>[] parameterTypes, Object... args) {
        ClassLoader classLoader = this.getClassLoader();
       *******************************************
        List<T> instances = this.createSpringFactoriesInstances(type, parameterTypes, classLoader, args, names);
        AnnotationAwareOrderComparator.sort(instances);
        return instances;
    }

3、获取监听器类
获取META-INF/spring.factories 配置的org.springframework.boot.SpringApplicationRunListener
OpfenFeign 没有配置该参数

代码同上只是这次直接取缓存的值
this.getSpringFactoriesInstances(ApplicationListener.class)

4、获取main函数

this.deduceMainApplicationClass()

启动

监听类启动

ConfigurableApplicationContext run(String… args)
1、先让EventPublishingRunListener 监听类启动

public ConfigurableApplicationContext run(String... args) {
      
        SpringApplicationRunListeners listeners = this.getRunListeners(args);
        listeners.starting();
}

初始化环境变量

ConfigurableEnvironment environment = this.prepareEnvironment(listeners, applicationArguments);
1、准备环境变量

private ConfigurableEnvironment prepareEnvironment(SpringApplicationRunListeners listeners, ApplicationArguments applicationArguments) {
		//默认SERVLET类型的环境
        ConfigurableEnvironment environment = this.getOrCreateEnvironment();
        this.configureEnvironment((ConfigurableEnvironment)environment, applicationArguments.getSourceArgs());
        //添加 configurationProperties到环境变量中
        ConfigurationPropertySources.attach((Environment)environment);
        listeners.environmentPrepared((ConfigurableEnvironment)environment);
        this.bindToSpringApplication((ConfigurableEnvironment)environment);
        if (!this.isCustomEnvironment) {
            environment = (new EnvironmentConverter(this.getClassLoader())).convertEnvironmentIfNecessary((ConfigurableEnvironment)environment, this.deduceEnvironmentClass());
        }

        ConfigurationPropertySources.attach((Environment)environment);
        return (ConfigurableEnvironment)environment;
    }

2、生成上下文ConfigurableApplicationContext 默认是 NONE

protected ConfigurableApplicationContext createApplicationContext() {
        Class<?> contextClass = this.applicationContextClass;
        if (contextClass == null) {
            try {
                switch(this.webApplicationType) {
                case SERVLET:
                    contextClass = Class.forName("org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext");
                    break;
                case REACTIVE:
                    contextClass = Class.forName("org.springframework.boot.web.reactive.context.AnnotationConfigReactiveWebServerApplicationContext");
                    break;
                default:
                    contextClass = Class.forName("org.springframework.context.annotation.AnnotationConfigApplicationContext");
                }
            } catch (ClassNotFoundException var3) {
                throw new IllegalStateException("Unable create a default ApplicationContext, please specify an ApplicationContextClass", var3);
            }
        }

        return (ConfigurableApplicationContext)BeanUtils.instantiateClass(contextClass);
    }

3、准备上下文

private void prepareContext(ConfigurableApplicationContext context, ConfigurableEnvironment environment, SpringApplicationRunListeners listeners, ApplicationArguments applicationArguments, Banner printedBanner) {
        context.setEnvironment(environment);
        this.postProcessApplicationContext(context);
        this.applyInitializers(context);
        listeners.contextPrepared(context);
        if (this.logStartupInfo) {
            this.logStartupInfo(context.getParent() == null);
            this.logStartupProfileInfo(context);
        }

        ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
        beanFactory.registerSingleton("springApplicationArguments", applicationArguments);
        if (printedBanner != null) {
            beanFactory.registerSingleton("springBootBanner", printedBanner);
        }

        if (beanFactory instanceof DefaultListableBeanFactory) {
            ((DefaultListableBeanFactory)beanFactory).setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
        }

        if (this.lazyInitialization) {
            context.addBeanFactoryPostProcessor(new LazyInitializationBeanFactoryPostProcessor());
        }

        Set<Object> sources = this.getAllSources();
        Assert.notEmpty(sources, "Sources must not be empty");
        this.load(context, sources.toArray(new Object[0]));
        listeners.contextLoaded(context);
    }

在这里插入图片描述

启动Srping 可以单独拆分出来分析

1 启动Srping

public void refresh() throws BeansException, IllegalStateException {
    Object var1 = this.startupShutdownMonitor;
    synchronized(this.startupShutdownMonitor) {
        /**
         *
         */
        this.prepareRefresh();
        /**
          2
         *子类容器执行内容
         * AbstractApplicationContext 是一个抽象类,定义了两个抽象方法
         * this.refreshBeanFactory();
         * this.getBeanFactory()
         * 具体内容由子类实现 ---委派模式
         * 子类:AbstractRefreshableApplicationContext;
         */
        ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
        /**
         * 配置容器特性
         */
        this.prepareBeanFactory(beanFactory);

        try {
            /**
             * 指定post事件
             */
            this.postProcessBeanFactory(beanFactory);
            /**
             * 调用所有注册的bean
             */
            this.invokeBeanFactoryPostProcessors(beanFactory);
            /**
             * 注册post事件
             */
            this.registerBeanPostProcessors(beanFactory);
            /**
             * 初试化信息源,国际化相关
             */
            this.initMessageSource();
            /**
             * 初试化容器事件传播器
             */
            this.initApplicationEventMulticaster();
            /**
             * 子类的某些特殊bean
             */
            this.onRefresh();
            /**
             * 注册监听器
             */
            this.registerListeners();
            /**
             * 初试化延迟加载的bean
             */
            this.finishBeanFactoryInitialization(beanFactory);
            /**
             * 容器的生命周期
             */
            this.finishRefresh();
        } catch (BeansException var9) {
            if (this.logger.isWarnEnabled()) {
                this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);
            }
        /**
         * 销毁 Bean
         */
            this.destroyBeans();
            //取消
            this.cancelRefresh(var9);
            throw var9;
        } finally {
            //重置缓存
            this.resetCommonCaches();
        }

    }
}

1.2.1 refreshBeanFactory

子类实现装在Bean loadBeanDefinitions();
子类:AbstractXmlApplicationContext;AnnotationConfigWebApplicationContext;GroovyWebApplicationContext;XmlWebApplicationContext

protected final void refreshBeanFactory() throws BeansException {
        if (this.hasBeanFactory()) {
            this.destroyBeans();
            this.closeBeanFactory();
        }

        try {
            //创建容器
            DefaultListableBeanFactory beanFactory = this.createBeanFactory();
            beanFactory.setSerializationId(this.getId());
            //设置IOC 容器
            this.customizeBeanFactory(beanFactory);
            //委派模式 子类实现容器加载Bean
            this.loadBeanDefinitions(beanFactory);
            this.beanFactory = beanFactory;
        } catch (IOException var2) {
            throw new ApplicationContextException("I/O error parsing bean definition source for " + this.getDisplayName(), var2);
        }
    }

版权声明:本文为Lihshan原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。