SpringBoot源码解析

5 篇文章 0 订阅

装载: https://blog.csdn.net/Oblak_ZY/article/details/124769216

SpringBoot源码解析

1.启动的过程:

在这里插入图片描述

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

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

  • 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的作用就是确定那些配置类是需要的,哪些是不需要的)
    在这里插入图片描述
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值