distiller的另一个实例正忙于启动_springboot的启动流程源码分析

本文详细分析了SpringBoot的启动流程,从SpringApplication对象的创建到run方法的执行,包括环境准备、监听器调用、Banner显示、上下文准备、自动装配机制等关键步骤。通过对源码的解读,揭示了SpringBoot如何加载配置、管理bean以及整合各种框架的核心原理。
摘要由CSDN通过智能技术生成

点击上方蓝色字体,选择“标星公众号”

优质文章,第一时间送达

  作者 |  yangxiaohui227 

来源 |  urlify.cn/6jeaiu

66套java从入门到精通实战课程分享

测试项目,随便一个简单的springboot项目即可:

4b52bf6bbcbfb0fa6a0901327bfefc1a.png

 直接debug调试:

2f63a3d011e63d83c6b64f28285191c4.png

 可见,分2步,第一步是创建SpringApplication对象,第二步是调用run方法:

1.SpringApplication对象的创建过程:

public SpringApplication(ResourceLoader resourceLoader, Class>... primarySources) { //resourceLoader为null,因为我们没有传入,primarySources这里包含主启动类的ThymeleafApplication.class
        this.resourceLoader = resourceLoader; //资源加载器,这里是null
        Assert.notNull(primarySources, "PrimarySources must not be null");
        this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources)); //将主启动类字节码存起来
        this.webApplicationType = WebApplicationType.deduceFromClasspath(); //检测当前的项目web类型,后续会分析
        setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));//这里涉及springboot的一个重要知识点,后续分析
        setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));//这里涉及springboot的一个重要知识点,后续分析
        this.mainApplicationClass = deduceMainApplicationClass();//这里检测main方法所在的类
    }

通过SpringApplication的创建过程,我们分析下,它的主要几个方法:

this.webApplicationType = WebApplicationType.deduceFromClasspath();

5fdc6719e1ea128ee9fae3ca771614b1.png

  因为我引入的是springboot-web相关依赖,所以,在本次测试项目中,webApplication的类型是AnnotationConfigServletWebServerApplicationContext

 setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class))和setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class)):
后续很多地方也会用到这个功能,在此解析下:所以上面2个方法分别是从spring.factories文件中,找到key为org.springframework.context.ApplicationContextInitializer 的所有值,然后创建对应的实例,另一个ApplicationListener同理

接下来我们分析下:this.mainApplicationClass = deduceMainApplicationClass();

检测main方法所在的类,我们自己写的代码,自己肯定很容易知道是哪个类,但springboot框架不知道,那怎么检测呢,我们先看一个异常栈信息:

d089623a87d2494882774b931f2a8492.png

 如上图所示,我们只要从一个异常的堆栈中就可以获取到main方法了,所以源码检测main方法也是一样的:

035516b220cb2c7ca5618338af075c24.png

 至此SpringApplication对象创建完毕,后续我们分析下它的run方法都做了些啥:

public ConfigurableApplicationContext run(String... args) {
     
        StopWatch stopWatch = new StopWatch(); //一个计时器,用于计算启动的时间
        stopWatch.start();//计时开始
        ConfigurableApplicationContext context = null;
        Collection exceptionReporters = new ArrayList<>();//异常报告器列表
        configureHeadlessProperty();//这个是给System对象设置一个属性:java.awt.headless=true
        SpringApplicationRunListeners listeners = getRunListeners(args); //从spring.factories文件中读取SpringApplicationRunListener的实现类,并创建对应的实例,这个类后续分析
        listeners.starting();//调用监听器的starting方法
        try {
            ApplicationArguments applicationArguments = new DefaultApplicationArguments(args); //这里仅仅是对请求参数进行封装成一个对象
            ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);//创建并配置环境的一些属性,然后调用监听器的相应方法,后续会分析
            configureIgnoreBeanInfo(environment);//往System对象中设置属性spr
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值