美文网首页
spring boot2.0启动原理

spring boot2.0启动原理

作者: 机灵鬼鬼 | 来源:发表于2020-11-19 14:59 被阅读0次

1)、准备环境
- 执行ApplicationContextInitializer.initialize()
- 监听器SpringApplicationRunListener回调contextPrepared
- 加载主配置类定义信息
- 监听器SpringApplicationRunListener回调contextLoaded

public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
        this.resourceLoader = resourceLoader;
        Assert.notNull(primarySources, "PrimarySources must not be null");
        this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
           //判断当前容器环境,判断是SERVLET还是webmvc还是REACTIVE
        this.webApplicationType = WebApplicationType.deduceFromClasspath();
    //从类路径下查找META-INF/spring.factories配置的所有ApplicationContextInitializer,然后保存起来。
        setInitializers((Collection) 
getSpringFactoriesInstances(ApplicationContextInitializer.class));
 //从类路径下查找META-INF/spring.factories配置的所有ApplicationListener,然后保存起来。
        setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
//从多个配置类中,找到带有main方法的主配置类
        this.mainApplicationClass = deduceMainApplicationClass();
    }

2)、刷新启动IOC容器
- 扫描加载所有容器中的组件
- 包括从META-INF/spring.factories中获取所有的EnableAutoConfiguration组件
3)、回调容器中所有ApplicationRunner、CommandLineRunner的run方法

public ConfigurableApplicationContext run(String... args) {
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        ConfigurableApplicationContext context = null;
        Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
        configureHeadlessProperty();
//获取SpringApplicationRunListeners ;从类路径下META-INF/spring.factories
        SpringApplicationRunListeners listeners = getRunListeners(args);
//循环遍历获取的listener,然后执行starting方法,启动起来。
        listeners.starting();
        try {
//封装命令行参数
            ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
//创建完成后回调SpringApplicationRunListeners.prepareEnvironment()方法,准备环境。
            ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);
            configureIgnoreBeanInfo(environment);
//打印Banner图标
            Banner printedBanner = printBanner(environment);
//创建ApplicationContext容器,会根据类型来判断创建容器种类
            context = createApplicationContext();
//异常分析报告
            exceptionReporters = getSpringFactoriesInstances(SpringBootExceptionReporter.class,
                    new Class[] { ConfigurableApplicationContext.class }, context);
//准备容器上下文环境;applyInitializers(context):内部逻辑会回调上方ApplicationContextInitializer对象的initialize方法。还要回调所有的SpringApplicationRunListener对象的contextPrepared方法。运行完之后回调SpringApplicationRunListener的contextLoaded方法
            prepareContext(context, environment, listeners, applicationArguments, printedBanner);
//刷新容器,初始化容器的所有组件,包括内嵌的web容器
            refreshContext(context);
//从ioc容器中获取所有的ApplicationRunner和CommandLineRunner进行回调,并且有次序。ApplicationRunner先回调,CommandLineRunner后回调。
            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 {
//调用SpringApplicationRunListeners的所有running方法,进行事件发布。
            listeners.running(context);
        }
        catch (Throwable ex) {
            handleRunFailure(context, ex, exceptionReporters, null);
            throw new IllegalStateException(ex);
        }
//整个spring容器启动完毕,返回带有所有资源的ioc容器
        return context;
    }

4)、监听器SpringApplicationRunListener回调running

相关文章

网友评论

      本文标题:spring boot2.0启动原理

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