前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >SpringBoot源码解析

SpringBoot源码解析

作者头像
botkenni
发布2022-09-23 20:51:11
1390
发布2022-09-23 20:51:11
举报
文章被收录于专栏:IT码农IT码农

SpringBoot源码解析

1.启动的过程:

在这里插入图片描述
在这里插入图片描述
  • 首先在main函数中启动当前应用程序(SpringApplication启动)
  • 创建SpringApplication对象(new SpringApplication()).在对象的构造方法中进行参数的初始化工作,最主要的是判断当前应用程序的类型以及初始化器和监听器,在此过程中会加载整个应用程序中的spring.factories文件,将文件的内容放在缓存对象中,方便后续获取,具体步骤如下:
    • 配置resourceloader
    • 判断当前应用程序的类型
    • 获取初始化器的实例对象
    • 获取监听器的实例对象
    • 找到当前应用程序的主类,开始执行
  • SpringApplication对象创建完成之后开始执行run()方法,来完成整个启动过程.而run方法中主要的步骤如下:
    • 设置启动时间
    • 设置上下文
    • 设置异常报告器
    • 创建监听器并从中获取符合监听事件的几个监听器
    • 配置命令行参数
    • 准备应用程序运行的环境
    • 接着是核心的上下文部分,分为prepareContext()上下文的前置处理,refreshContext()核心方法,就是spring中的refresh()方法,其中的beanFactoryPostProcessor()完成自动装配的核心,afterRefresh()上下文后置结束处理
    • 之后就是发布应用上下文启动,执行runner()运行器
    • 发布应用上下文就绪并返回
    • SpringApplication启动结束

2.具体的run()方法源码如下:

代码语言:javascript
复制
public ConfigurableApplicationContext run(String... args) {
   
   		//设置启动时间
        long startTime = System.nanoTime();
    	//设置上下文
        DefaultBootstrapContext bootstrapContext = this.createBootstrapContext();
        ConfigurableApplicationContext context = null;
        this.configureHeadlessProperty();
    	//创建监听器并从中获取符合监听事件的几个监听器
        SpringApplicationRunListeners listeners = this.getRunListeners(args);
        listeners.starting(bootstrapContext, this.mainApplicationClass);

        try {
   
            //配置命令行参数
            ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
            //准备应用程序运行的环境
            ConfigurableEnvironment environment = this.prepareEnvironment(listeners, bootstrapContext, applicationArguments);
            this.configureIgnoreBeanInfo(environment);
            //打印banner(也就是那个p用没有的图标)
            Banner printedBanner = this.printBanner(environment);
            context = this.createApplicationContext();
            context.setApplicationStartup(this.applicationStartup);
            //prepareContext和refreshContext是自动装配的核心方法 而且这个refreshContext方法就是spring中的refresh()方法 使用的就是里面的beanFactoryPostProcessor()来实现的自动装配
            this.prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);
            this.refreshContext(context);
            this.afterRefresh(context, applicationArguments);
            Duration timeTakenToStartup = Duration.ofNanos(System.nanoTime() - startTime);
            //发布应用上下文启动,执行runner()运行器
            if (this.logStartupInfo) {
   
                (new StartupInfoLogger(this.mainApplicationClass)).logStarted(this.getApplicationLog(), timeTakenToStartup);
            }

            listeners.started(context, timeTakenToStartup);
            this.callRunners(context, applicationArguments);
        } catch (Throwable var12) {
   
            this.handleRunFailure(context, var12, listeners);
            throw new IllegalStateException(var12);
        }
    
		//发布应用上下文就绪并返回
        try {
   
            Duration timeTakenToReady = Duration.ofNanos(System.nanoTime() - startTime);
            listeners.ready(context, timeTakenToReady);
            return context;
        } catch (Throwable var11) {
   
            this.handleRunFailure(context, var11, (SpringApplicationRunListeners)null);
            throw new IllegalStateException(var11);
        }
    }

3.自动装配的原理

自动装配的实现就是为了从spring.factories文件中获取到对应的bean对象,并且由spring容器帮我们进行管理.

  • 当启动SpringBoot应用程序的时候会先创建SpringApplication对象,在对象的构造方法中进行参数的初始化工作,最主要的是判断当前应用程序的类型以及初始化器和监听器,在此过程中会加载整个应用程序中的spring.factories文件,将文件的内容放在缓存对象中,方便后续获取
  • SpringBoot对象创建完成之后,开始执行run()方法来完成整个启动过程.启动过程中主要包括的两个方法:prepareContext()和refreshContext()方法,在这两个关键的步骤中完成自动装配的核心功能
  • 在prepareContext()方法中主要完成的是对上下文对象的初始化操作,包括属性值的设置,在整个过程中最重要的方法是load(),主要完成将当前启动类作为一个beanDefinition注册到registry(注册表)中,方便后续进行BeanFactoryPostProcesser调用执行的时候,找到对应的主类,来完成对@SpringBootApplication,@EnableAutoConfiguration等注解的解析工作(注意:要完成这些注解的解析工作,必须要获取到启动类)
  • 在refreshContext()方法中,会调用spring中的refresh()方法(refresh()方法一共有13个非常关键的方法来完成整个spring应用程序的启动),在自动装配中会调用invokeBeanFactoryPostProcessor()方法,在此方法中主要是对ConfigurationClassPathPostProcessor类的处理(它是BeanFactoryPostProcessor的子类,也是BeanDefinitionReaderPostProcessor的子类).在调用的时候会先调用BeanDefinitionReaderPostProcessor中的postProcessorBeanDefinitionRegistry方法,然后调用PostProcessBeanFactory()方法,在执行postProcessorBeanDefinitionRegistry方法的时候会解析处理各种注解,最主要的是对@Import注解的解析
  • 在解析@Impo注解的时候,会有一个getInstance()方法,从主类中递归解析注解,把所有@Import的注解都解析到,然后在processImport()方法中对Import的类进行分类,此处主要识别的是@Import(AutoConfigurationImportSelect.class)中的AutoConfigurationImportSelect,在后续的过程中调用deferredImportSelectorHandler()中的方法来完成EnableAutoConfiguration对象的加载,之后获取到spring.factories找到大量的自动装配的类(并不是所有的类都会用到),将不适用的装配类移除,过滤掉多余的装配类(starter的作用就是确定那些配置类是需要的,哪些是不需要的)
在这里插入图片描述
在这里插入图片描述
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2022-09-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • SpringBoot源码解析
    • 1.启动的过程:
      • 2.具体的run()方法源码如下:
        • 3.自动装配的原理
        相关产品与服务
        容器服务
        腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档