SpringBoot:run()方法

SpringBoot:run()方法
1、run方法的执行过程。
public ConfigurableApplicationContext run(String... args) {
        //创建时间对象并启动计时。
        StopWatch stopWatch = new StopWatch();
        //设置任务名称。
        stopWatch.start();
        //这就是传说中的 IOC容器,实则是个 ConfigurableApplicationContext 对象,先创建出来,再往里面填东西。
        ConfigurableApplicationContext context = null;
        Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList();
        //设置当前应用为 headless 模式。
        this.configureHeadlessProperty();
        //获取运行时监听器,并开始监听。
        SpringApplicationRunListeners listeners = this.getRunListeners(args);
        listeners.starting();

        Collection exceptionReporters;
        try {
            //准备环境。
            ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
            ConfigurableEnvironment environment = this.prepareEnvironment(listeners, applicationArguments);
            this.configureIgnoreBeanInfo(environment);
            //打印 banner。
            Banner printedBanner = this.printBanner(environment);
            //创建context。
            context = this.createApplicationContext();
            exceptionReporters = this.getSpringFactoriesInstances(SpringBootExceptionReporter.class, new Class[]{ConfigurableApplicationContext.class}, context);
            //准备context。
            this.prepareContext(context, environment, listeners, applicationArguments, printedBanner);
            //刷新context。
            this.refreshContext(context);
            this.afterRefresh(context, applicationArguments);
            stopWatch.stop();
            if (this.logStartupInfo) {
                (new StartupInfoLogger(this.mainApplicationClass)).logStarted(this.getApplicationLog(), stopWatch);
            }

            listeners.started(context);
            this.callRunners(context, applicationArguments);
        } catch (Throwable var10) {
            this.handleRunFailure(context, var10, exceptionReporters, listeners);
            throw new IllegalStateException(var10);
        }

        try {
            listeners.running(context);
            return context;
        } catch (Throwable var9) {
            this.handleRunFailure(context, var9, exceptionReporters, (SpringApplicationRunListeners)null);
            throw new IllegalStateException(var9);
        }
    }

1、 创建时间对象并启动计时。

2、创建 IOC 容器。

3、设置当前应用为 headless 模式。将应用程序设置为这种模式,是为了告诉程序,“你所在的服务器上缺少些硬件,没有显示器、鼠标、或者其他”。这就是一个赋值过程,不需要深究。

4、获取运行时监听器,并开始监听。

5、准备环境。应用程序运行在服务器上,而且它的运行需要依赖一些资源,比如 JDK、maven 库、文件编码格式等等。那应用程序是怎么知道这些资源都放在哪里的?或者这些属性值是什么?从而能正确读取。是因为应用程度在启动过程中创建了环境对象,它里面有个字段(成员变量):MutablePropertySources propertySources ,所有的资源属性在应用程度启动过程中被包装成 propertySource 存放在 propertySources 中。后面开发者如果有需要直接在 环境对象中拿这些资源就可以了。除此以外,开发者可以使用 @propertySource 将自定义的配置文件导入到 环境对象中,最后被代码块调用。

ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
ConfigurableEnvironment environment = this.prepareEnvironment(listeners, applicationArguments);

5.1、跟进this.prepareEnvironment(listeners, applicationArguments)。

  private ConfigurableEnvironment prepareEnvironment(SpringApplicationRunListeners listeners, ApplicationArguments applicationArguments) {
        //创建环境对象。
        ConfigurableEnvironment environment = this.getOrCreateEnvironment();
        //配置环境对象。
        this.configureEnvironment((ConfigurableEnvironment)environment, applicationArguments.getSourceArgs());
        //绑定环境对象。
        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;
    }

6、打印 banner。是否打印 logo 可以在 application.properties 中配置,logo 的图案也可以修改。

7、创建 context。

8、准备 context。

9、刷新 context。将应用程序运行所需要的所有 bean(包括开发者自己写的) 加载到了 context 的 beanFactory 中。

9.1、要自动配置的类得先写好了,加上注解,包存在 .java 文件中。
9.2、在启动过程中调用 BeanFactoryPostProcesser 的某个实现类,它为需要自动配置的每一个类创造一个对应的 beanDefinition,并将所有的 beanDefinition 保存(注册) 到 context 中。(实际上是为每一个类构建键值对 className:BeanDefinion 保存到了 context 中的 beanFactory 属性的 beanDefinitionMap 属性中)。

9.3、接着再遍历 beanDefinitionMap,根据 className 从 context 中先获取对应的 bean,如果能拿到,就表示这个类已经被注册了,如果拿不到,那就通过 BeanDefinion 创建一个新 bean 注册到 context中。(实际上是从 context 中的 beanFactory 属性的 singletonObject 属性中拿 bean,如果拿不到,创建的新 bean 也是保存到 signletonObject 中)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一只尘世中迷途小书童

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值