【Spring-Boot】源码 简解析 之 启动流程

扫码关注公众号:Java 技术驿站

发送:vip
将链接复制到本浏览器,永久解锁本站全部文章

【公众号:Java 技术驿站】 【加作者微信交流技术,拉技术群】
断点源码

只分析主要方法
源码版本:1.5.10

    package com.example.demo;

    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;

    @SpringBootApplication
    public class DemoApplication {

        public static void main(String[] args) {
            SpringApplication.run(DemoApplication.class, args);
        }
    }
@SpringBootApplication包含以下三个注解
    // 使用JavaConfig形式,不用xml
    @SpringBootConfiguration
    // 开启自动配置
    @EnableAutoConfiguration
    // 自动包扫描
    @ComponentScan
1. initialize方法
    private void initialize(Object[] sources) {

            // 1.初始化成员变量sources
            if (sources != null && sources.length > 0) {
                this.sources.addAll(Arrays.asList(sources));
            }

            // 2.初始化成员变量webEnvironment,判断应用类型
            // javax.servlet.Servlet 或者 org.springframework.web.context.ConfigurableWebApplicationContext
            this.webEnvironment = deduceWebEnvironment();

            // 3.初始化成员变量initializers
            // spring.factories文件中key为ApplicationContextInitializer的类实例化
            // 设置到SpringApplication的initializers属性中,找出所有的应用程序初始化器
            setInitializers((Collection) getSpringFactoriesInstances(
                    ApplicationContextInitializer.class));

            // 4.初始化成员变量listeners
            // spring.factories文件中key为ApplicationListener的类实例化
            // 设置到SpringApplication的listeners属性中,找出所有的应用程序事件监听器 
            setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));

            // 5.初始化成员变量mainApplicationClass,找应用的入口类
            this.mainApplicationClass = deduceMainApplicationClass();
        }
2. run方法
    public ConfigurableApplicationContext run(String... args) {

            // 1.开始记录时间
            StopWatch stopWatch = new StopWatch();
            stopWatch.start();
            ConfigurableApplicationContext context = null;
            FailureAnalyzers analyzers = null;

            // 2.设置java.awt.headless系统属性为true
            configureHeadlessProperty();

            // 3.获取SpringApplicationRunListeners,内部只有一个EventPublishingRunListener
            SpringApplicationRunListeners listeners = getRunListeners(args);

            // 4.接受ApplicationStartedEvent事件的listener会执行相应的操作
            listeners.starting();
            try {

                // 5.构造一个应用程序参数持有类
                ApplicationArguments applicationArguments = new DefaultApplicationArguments(
                        args);

                // 6.根据SpringApplicationRunListeners以及参数来准备环境 
                ConfigurableEnvironment environment = prepareEnvironment(listeners,
                        applicationArguments);

                // 7.打印logo
                Banner printedBanner = printBanner(environment);

                // 8.创建Spring容器
                context = createApplicationContext();

                // 9.创建异常分析器 
                analyzers = new FailureAnalyzers(context);

                // 10.Spring上下文前置处理
                prepareContext(context, environment, listeners, applicationArguments,
                        printedBanner);

                // 11.Spring上下文刷新
                refreshContext(context);

                // 12.容器创建完成之后执行额外一些操作
                afterRefresh(context, applicationArguments);

                // 13.广播出ApplicationReadyEvent事件给相应的监听器执行
                listeners.finished(context, null);

                // 14.停止计时
                stopWatch.stop();
                if (this.logStartupInfo) {
                    new StartupInfoLogger(this.mainApplicationClass)
                            .logStarted(getApplicationLog(), stopWatch);
                }
                return context;
            }
            catch (Throwable ex) {
                handleRunFailure(context, listeners, analyzers, ex);
                throw new IllegalStateException(ex);
            }
        }
3. run方法中的prepareContext方法
    private void prepareContext(ConfigurableApplicationContext context,
                ConfigurableEnvironment environment, SpringApplicationRunListeners listeners,
                ApplicationArguments applicationArguments, Banner printedBanner) {

            // 1.把环境和上下文关联起来
            context.setEnvironment(environment);

            // 2.为上下文配置Bean生成器以及资源加载器
            postProcessApplicationContext(context);

            // 3.调用初始化器
            applyInitializers(context);

            // 4.触发Spring Boot启动过程的contextPrepared事件
            listeners.contextPrepared(context);
            if (this.logStartupInfo) {
                logStartupInfo(context.getParent() == null);
                logStartupProfileInfo(context);
            }

            // Add boot specific singleton beans
            // 5.添加两个Spring Boot中的特殊单例Bean:springApplicationArguments和springBootBanner
            context.getBeanFactory().registerSingleton("springApplicationArguments",
                    applicationArguments);
            if (printedBanner != null) {
                context.getBeanFactory().registerSingleton("springBootBanner", printedBanner);
            }

            // Load the sources
            // 6.加载sources:对于DemoApplication而言,这里的sources集合只包含了它一个class对象
            Set<Object> sources = getSources();
            Assert.notEmpty(sources, "Sources must not be empty");

            // 7.加载动作:构造BeanDefinitionLoader并完成Bean定义的加载
            load(context, sources.toArray(new Object[sources.size()]));

            // 8.触发Spring Boot启动过程的contextLoaded事件
            listeners.contextLoaded(context);
        }

来源:http://ddrv.cn

赞(0) 打赏
版权归原创作者所有,任何形式的转载请联系博主:daming_90:Java 技术驿站 » 【Spring-Boot】源码 简解析 之 启动流程

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏