SpringBoot启动过程源码解析

SpringBoot启动过程

核心组件:
● Application Events and Listeners
    ApplicationContextInitializer
    ApplicationListener
    SpringApplicationRunListener
● ApplicationRunner 与 CommandLineRunner
1、创建 SpringApplication
在这里插入图片描述
判断当前应用程序类型是servlet还是响应式编程
在这里插入图片描述
bootstrapRegistryInitializers:初始启动引导器(List),去spring.factories文件中找 org.springframework.boot.Bootstrappe
在这里插入图片描述
initializers:初始化器(List<ApplicationContextInitializer<?>>),去spring.factories找 ApplicationContextInitializer
在这里插入图片描述

listeners:应用监听器(List<ApplicationListener<?>>),去spring.factories找 ApplicationListener
在这里插入图片描述

2、运行 SpringApplication的run方法
在这里插入图片描述
创建引导上下文(Context环境),获取到所有之前的 bootstrapRegistryInitializers挨个执行 intitialize() 来完成对引导启动器上下文环境设置
在这里插入图片描述
获取所有 RunListener(运行监听器),去spring.factories找 SpringApplicationRunListener.
在这里插入图片描述
准备环境
在这里插入图片描述
调用prepareEnvironment()方法

private ConfigurableEnvironment prepareEnvironment(SpringApplicationRunListeners listeners, DefaultBootstrapContext bootstrapContext, ApplicationArguments applicationArguments) {
		//返回或者创建基础环境信息对象。StandardServletEnvironment
        ConfigurableEnvironment environment = this.getOrCreateEnvironment();
        //配置环境信息对象,读取所有的配置源的配置属性值。
        this.configureEnvironment((ConfigurableEnvironment)environment, applicationArguments.getSourceArgs());
        //绑定环境信息
        ConfigurationPropertySources.attach((Environment)environment);
        //监听器调用 listener.environmentPrepared(),通知所有的监听器当前环境准备完成
        listeners.environmentPrepared(bootstrapContext, (ConfigurableEnvironment)environment);
        DefaultPropertiesPropertySource.moveToEnd((ConfigurableEnvironment)environment);
        Assert.state(!((ConfigurableEnvironment)environment).containsProperty("spring.main.environment-prefix"), "Environment prefix cannot be set via properties.");
        this.bindToSpringApplication((ConfigurableEnvironment)environment);
        if (!this.isCustomEnvironment) {
            environment = this.convertEnvironment((ConfigurableEnvironment)environment);
        }

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

通过createApplicationContext()方法创建IOC容器(),它会根据项目类型(Servlet)创建对应的容器(AnnotationConfigServletWebServerApplicationContext)。
在这里插入图片描述
通过prepareContext()会准备ApplicationContext IOC容器的基本信息
在这里插入图片描述

● IOC容器的后置处理流程。
● 遍历所有的 ApplicationContextInitializer 。调用 initialize.。来对ioc容器进行初始化扩展功能
● 遍历所有的 listener 调用 contextPrepared。EventPublishRunListenr;通知所有的监听器contextPrepared
在这里插入图片描述
所有的监听器 调用 contextLoaded。通知所有的监听器 contextLoaded;
在这里插入图片描述
核心代码,通过refreshContext()方法刷新IOC容器。 创建容器中的所有组件(Spring注解)。
在这里插入图片描述
通过callRunners()方法调用所有runners
在这里插入图片描述
获取容器中的 ApplicationRunner 和CommandLineRunner
在这里插入图片描述
遍历所有的runner。调用 run 方法
在这里插入图片描述
调用所有监听器的 ready()方法 , 通知所有的监听器程序正在运行。
在这里插入图片描述

自定义监听事件组件

1、编写核心组件类
MyApplicationContextInitializer

public class MyApplicationContextInitializer implements ApplicationContextInitializer {
    @Override
    public void initialize(ConfigurableApplicationContext applicationContext) {
        System.out.println("MyApplicationContextInitializer.class...initialize()");
    }
}

MyApplicationListener

public class MyApplicationListener implements ApplicationListener {
    @Override
    public void onApplicationEvent(ApplicationEvent event) {
        System.out.println("MyApplicationListener.class...onApplicationEvent()");
    }
}

MySpringApplicationRunListener

public class MySpringApplicationRunListener implements SpringApplicationRunListener {

    private final SpringApplication application;

    public MySpringApplicationRunListener(SpringApplication application, String[] args) {
        this.application = application;
    }

    @Override
    public void starting(ConfigurableBootstrapContext bootstrapContext) {
        System.out.println("MySpringApplicationRunListener.class...starting()");
    }

    @Override
    public void environmentPrepared(ConfigurableBootstrapContext bootstrapContext, ConfigurableEnvironment environment) {
        System.out.println("MySpringApplicationRunListener.class...environmentPrepared()");
    }

    @Override
    public void contextPrepared(ConfigurableApplicationContext context) {
        System.out.println("MySpringApplicationRunListener.class...contextPrepared()");
    }

    @Override
    public void contextLoaded(ConfigurableApplicationContext context) {
        System.out.println("MySpringApplicationRunListener.class...contextLoaded()");
    }

    @Override
    public void started(ConfigurableApplicationContext context, Duration timeTaken) {
        System.out.println("MySpringApplicationRunListener.class...started()");
    }

    @Override
    public void ready(ConfigurableApplicationContext context, Duration timeTaken) {
        System.out.println("MySpringApplicationRunListener.class...ready()");
    }

    @Override
    public void failed(ConfigurableApplicationContext context, Throwable exception) {
        System.out.println("MySpringApplicationRunListener.class...failed()");
    }
}

2、把两个runner加入到容器中,可以按照@Order进行排序
MyApplicationRunner

@Order(2)
@Component
public class MyApplicationRunner implements ApplicationRunner {
    @Override
    public void run(ApplicationArguments args) throws Exception {
        System.out.println("MyApplicationRunner.class...run()");
    }
}

MyCommandLineRunner

@Order(1)
@Component
public class MyCommandLineRunner implements CommandLineRunner {
    @Override
    public void run(String... args) throws Exception {
        System.out.println("MyCommandLineRunner.class...run()");
    }
}

3、编写配置文件
在这里插入图片描述

# Application Context Initializers
org.springframework.context.ApplicationContextInitializer=\
    com.example.demo.listen.MyApplicationContextInitializer

# Application Listeners
org.springframework.context.ApplicationListener=\
    com.example.demo.listen.MyApplicationListener

# Run Listeners
org.springframework.boot.SpringApplicationRunListener=\
    com.example.demo.listen.MySpringApplicationRunListener
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值