欢迎来到皮皮网网首页

【体质评测源码】【源码解析mybatis 腾讯】【springboot源码哪里下】springboots 启动源码_springboot启动源码解析

来源:webpack模块遍历源码 时间:2024-11-25 03:37:20

1.Spring Boot 3系列之-启动类详解
2.SpringBoot源码学习——SpringBoot自动装配源码解析+Spring如何处理配置类的启t启
3.spring启动原理(spring工程启动)
4.SpringBoot源码 | refreshContext方法解析
5.头秃了,二十三张图带你从源码了解SpringBoot启动流程!动源动源
6.springboot如何启动内置tomcat?(源码详解)

springboots 启动源码_springboot启动源码解析

Spring Boot 3系列之-启动类详解

       Spring Boot简化了Spring应用程序的码s码解开发与部署,让开发者专注于业务逻辑。启t启在Spring Boot项目中,动源动源启动类是码s码解体质评测源码入口点,通常在根路径下,启t启标注了 @SpringBootApplication。动源动源此注解集成了配置、码s码解组件扫描、启t启自动配置等功能,动源动源减少配置工作。码s码解

       启动类上 @SpringBootApplication 注解,启t启组合了三个注解:@SpringBootConfiguration,动源动源 @EnableAutoConfiguration 和 @ComponentScan。@SpringBootConfiguration 是码s码解配置类注解,@EnableAutoConfiguration 自动配置组件,@ComponentScan 扫描并注册组件。

       源码展示:@SpringBootConfiguration 与 @Configuration 类似,用于标注配置类。@EnableAutoConfiguration 根据依赖自动配置组件。@ComponentScan 指定扫描包,自动注册组件。

       通过这些注解,Spring Boot简化了应用程序构建,自动配置组件,减少手动配置。源码解析mybatis 腾讯理解这些注解的用法,可以更高效地开发Spring Boot应用。

SpringBoot源码学习——SpringBoot自动装配源码解析+Spring如何处理配置类的

       SpringBoot通过SPI机制,借助外部引用jar包中的META-INF/spring.factories文件,实现引入starter即可激活功能,简化手动配置bean,实现即开即用。

       启动SpringBoot服务,通常使用Main方法启动,其中@SpringBootApplication注解包含@SpringBootConfiguration、@EnableAutoConfiguration、@ComponentScan,自动装配的核心。

       深入分析@SpringBootApplication,其实质是执行了@SpringBootConfiguration、@EnableAutoConfiguration、@ComponentScan三个注解的功能,简化了配置过程,强调了约定大于配置的思想。

       SpringBoot的自动装配原理着重于研究如何初始化ApplicationContext,Spring依赖于ApplicationContext实现其功能,SpringApplication#run方法为初始化ApplicationContext的入口。

       分析SpringApplication构造方法,SpringApplication.run(启动类.class, args) 实际调用的是该方法,其关键在于根据项目类型反射生成合适的springboot源码哪里下ApplicationContext。

       选择AnnotationConfigServletWebServerApplicationContext,此上下文具备启动Servlet服务器和注册Servlet或过滤器类型bean的能力。

       准备刷新ApplicationContext,SpringBoot将主类注册到Spring容器中,以便@ConfigurationClassPostProcessor解析主类注解,发挥@Import、@ComponentScan的作用。

       刷新ApplicationContext过程包括一系列前置准备,如将主类信息封装成AnnotatedGenericBeanDefinition,解析注解并调用BeanDefinitionCustomizer自定义处理。

       解析配置类中的注解,通过BeanDefinitionRegistryPostProcessor和ConfigurationClassParser实现,筛选、排序候选者,并解析@Import注解实现自动装配。

       增强配置类,ConfigurationClassPostProcessor对full模式的配置进行增强,确保@Import正确处理,CGLIB用于增强原配置类,确保生命周期完整,避免真正执行@Bean方法逻辑。

       深入解析AutoConfigurationImportSelector实现自动装配,通过spring.boot.enableautoconfiguration设置开启状态,读取spring-autoconfigure-metadata.properties和META-INF/spring.factories文件,筛选并加载自动配置类。安卓指纹源码

spring启动原理(spring工程启动)

       SpringBoot启动原理分析

       è‡ªåŠ¨é…ç½®æ ¸å¿ƒç±»SpringFactoriesLoader

       ä¸Šé¢åœ¨è¯´@EnableAutoConfiguration的时候有说META-INF下的spring.factories文件,那么这个文件是怎么被spring加载到的呢,其实就是SpringFactoriesLoader类。

       SpringFactoriesLoader是一个供Spring内部使用的通用工厂装载器宏闭,SpringFactoriesLoader里有两个方法,

       åœ¨è¿™ä¸ªSpringBoot应用启动过程中,SpringFactoriesLoader做了以下几件事:

       åŠ è½½æ‰€æœ‰META-INF/spring.factories中的Initializer

       åŠ è½½æ‰€æœ‰META-INF/spring.factories中的Listener

       åŠ è½½EnvironmentPostProcessor(允许在Spring应用构建之前定制环境配置)

       æŽ¥ä¸‹æ¥åŠ è½½Properties和YAML的PropertySourceLoader(针对SpringBoot的两种配置文件的加载器)

       å„种异常情况的FailureAnalyzer(异常解释器)

       åŠ è½½SpringBoot内部实现的各种AutoConfiguration

       æ¨¡æ¿å¼•æ“ŽTemplateAvailabilityProvider(如Freemarker、Thymeleaf、Jsp、Velocity等)

       æ€»å¾—来说,SpringFactoriesLoader和@EnableAutoConfiguration配合起来,整体功能就是查找spring.factories文件,加载自动配置类。

       æ•´ä½“启动流程

       åœ¨æˆ‘们执行入口类的main方法之后,运行SpringApplication.run,后面new了一个SpringApplication对象,然后执行它的run方法。

       åˆå§‹åŒ–SpringApplicationç±»

       åˆ›å»ºä¸€ä¸ªSpringApplication对象时,会调用它自己的initialize方法

       æ‰§è¡Œæ ¸å¿ƒrun方法

       åˆå§‹åŒ–initialize方法执行完之后,会调用run方法,开始启动SpringBoot。

       é¦–先遍历执行所有通过SpringFactoriesLoader,在当前classpath下的META-INF/spring.factories中查找所有可用的SpringApplicationRunListeners并实例化。调用它们的starting()方法,液蔽通知这些监听器SpringBoot应用启动。

       åˆ›å»ºå¹¶é…ç½®å½“前SpringBoot应用将要使用的Environment,包括当前有效的PropertySource以及Profile。

       éåŽ†è°ƒç”¨æ‰€æœ‰çš„SpringApplicationRunListeners的environmentPrepared()的方法,通知这些监听器SpringBoot应用的Environment已经完成初始化。

       æ‰“印SpringBoot应用的banner,SpringApplication的showBanner属性为true时,如果classpath下存在banner.txt文件,则打印其内容,否则打印默认banner。

       æ ¹æ®å¯åŠ¨æ—¶è®¾ç½®çš„applicationContextClass和在initialize方法设置的webEnvironment,创建对应的applicationContext。

       åˆ›å»ºå¼‚常解析器,用在启动中发生异常的时候进行异常处理(包括记录日志、释放资源等)。

       è®¾ç½®SpringBoot的Environment,注册SpringBean名称的序列化器BeanNameGenerator,并设置资源加载器ResourceLoader,通过SpringFactoriesLoader加载ApplicationContextInitializer初始化器,调用initialize方法,对创建的ApplicationContext进一步初始化。

       è°ƒç”¨æ‰€æœ‰çš„SpringApplicationRunListeners的contextPrepared方法,通知闹绝州这些Listener当前ApplicationContext已经创建完毕。

       æœ€æ ¸å¿ƒçš„一步,将之前通过@EnableAutoConfiguration获取的所有配置以及其他形式的IoC容器配置加载到已经准备完毕的ApplicationContext。

       è°ƒç”¨æ‰€æœ‰çš„SpringApplicationRunListener的contextLoaded方法,加载准备完毕的ApplicationContext。

       è°ƒç”¨refreshContext,注册一个关闭Spring容器的钩子ShutdownHook,当程序在停止的时候释放资源(包括:销毁Bean,关闭SpringBean的创建工厂等)

       æ³¨ï¼šé’©å­å¯ä»¥åœ¨ä»¥ä¸‹å‡ ç§åœºæ™¯ä¸­è¢«è°ƒç”¨ï¼š

       1)程序正常退出

       2)使用System.exit()

       3)终端使用Ctrl+C触发的中断

       4)系统关闭

       5)使用Killpid命令杀死进程

       èŽ·å–当前所有ApplicationRunner和CommandLineRunner接口的实现类,执行其run方法

       éåŽ†æ‰€æœ‰çš„SpringApplicationRunListener的finished()方法,完成SpringBoot的启动。

       spring工作原理

       Spring的工作原理是让一个对象的创建不用new就可以自动的生产,在运行时与xmlSpring的配置文件来高岩动态的创建对象和调用对象,而不需要通过代码来关联。

       Spring是一个开放源代码的设计层面框架,他解决的是业务逻辑层和其他各层的松耦合问题,因此它将面向接口的编程思想贯穿整个系统应用。

       spring特点是1.方便解耦,简化开发。2.AOP编程的支持。3.声明式事务的支持。4.方便程序的测试。5.方便集成各种优秀框架。6.降低JavaEEAPI的使用难度。7.Java源码是经典学习范例。

       Spring框架是由于软件开发的复杂性而创建的。Spring使用的是基本的JavaBean来完成以前只可能由EJB完成的事情。然而,Spring的用途不仅仅限于服务器端的开发。从简单性、可测试性和松耦合性角度而言,绝大部分Java应用都可以从Spring中带消受益。Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架。

       Spring通过一种称作控制反转(IoC)的技术促进了松耦合。当应用了IoC,一个对象依赖的其它对象会通过被动的方式传递进来,而不是这个对象自己创建或者查找依赖对象。你可以认为IoC与JNDI相反——不是对象从容器中查找依赖,而是容器在对象初戚行御始化时不等对象请求就主动将依赖传递给它。

spring的原理是什么?

       ä¸€ã€IoC(Inversionofcontrol):控制反转\x0d\1、IoC:\x0d\概念:控制权由对象本身转向容器;由容器根据配置蠢衫文件去创建实例并创建各个实例之间的依赖关系\x0d\核心:bean工厂;在Spring中,bean工厂创建的各个实例称作bean\x0d\二、AOP(Aspect-OrientedProgramming):面向方面编程。\x0d\1、代理的两种方式:\x0d\静态代理:\x0d\针对每个具体类分别编写代理类。\x0d\针对一个接口编写一个代理类。\x0d\动态代理:\x0d\针对一个方面编写一个InvocationHandler,然后借用JDK反射包中的Proxy类为各种接口动态生成相应的代理类。\x0d\2、AOP的主要原理:动态代理。\x0d\Spring工作原理\x0d\Spring已经用过一段时间了,感觉Spring是个很不错的框架。内部最核心的就是IOC了,\x0d\动态注入,让一个对象的创建不用new了,可以自动的生产,这其实就是利用java里的反射,反射其实就是在运行时动态的去创建、调用对象,Spring就是在运行时,跟xmlSpring的配置文件来动态的创建对象,和调用对象里的方法的。\x0d\Spring还有一个核心就是AOP这个就是面向切面编程,可以为某一类对象进行监督和控制(也就是在调用这类对象的具体方法的前后去调用你指定的模块)从而达到对一个模块扩充的功能。这些都是通过配置类达到谈庆的。\x0d\Spring目的含档握:就是让对象与对象(模块与模块)之间的关系没有通过代码来关联,都是通过配置类说明管理的(Spring根据这些配置内部通过反射去动态的组装对象)\x0d\要记住:Spring是一个容器,凡是在容器里的对象才会有Spring所提供的这些服务和功能。\x0d\Spring里用的最经典的一个设计模式就是:模板方法模式。

SpringBoot应用启动原理(二)扩展URLClassLoader实现嵌套jar加载

       åœ¨ä¸Šç¯‡æ–‡ç« ã€ŠSpringBoot应用启动原理(一)将启动脚本嵌入jar》中介绍了SpringBoot如何将启动脚本与RunnableJar整合为ExecutableJar的原理,使得生成的jar/war文件可以直接启动

       æœ¬ç¯‡å°†ä»‹ç»SpringBoot如何扩展URLClassLoader实现嵌套jar的类(资源)加载,以启动我们的应友枣旁用。

       é¦–先岩伏,从一个简单的示例开始

       build.gradle

       WebApp.java

       æ‰§è¡Œgradlebuild构建jar包,里面包含应用程序、第三方依赖以及SpringBoot启动程序,其目录结构如下

       æŸ¥çœ‹MANIFEST.MF的内容(MANIFEST.MF文件的作用请自行GOOGLE)

       å¯ä»¥çœ‹åˆ°ï¼Œjar的启动类为org.springframework.boot.loader.JarLauncher,而并不是我们的com.manerfan.SpringBoot.theory.WebApp,应用程序入口类被标记为了Start-Class

       jar启动并不是通过应用程序入口类,而是通过JarLauncher代理启动。其实SpringBoot拥有3中不同的Launcher:JarLauncher、WarLauncher、PropertiesLauncher

       SpringBoot使用Launcher代理启动,其最重要的一点便是可以自定义ClassLoader,以实现对jar文件内(jarinjar)或其他路径下jar、class或资源文件的加载

       å…³äºŽClassLoader的更多介绍可参考《深入理解JVM之ClassLoader》

       SpringBoot抽象了Archive的概念,一个Archive可以是jar(JarFileArchive),可以是一个文件目录(ExplodedArchive),可以抽象为统一访问资源的逻辑层。

       ä¸Šä¾‹ä¸­ï¼Œspring-boot-theory-1.0.0.jar既为一个JarFileArchive,spring-boot-theory-1.0.0.jar!/BOOT-INF/lib下的每一个jar包也是一个JarFileArchive

       å°†spring-boot-theory-1.0.0.jar解压到目录spring-boot-theory-1.0.0,则目录spring-boot-theory-1.0.0为一个ExplodedArchive

       æŒ‰ç…§å®šä¹‰ï¼ŒJarLauncher可以加载内部/BOOT-INF/lib下的jar及/BOOT-INF/classes下的应用class

       å…¶å®žJarLauncher实现很简单

       å…¶ä¸»å…¥å£æ–°å»ºäº†JarLauncher并调用父类Launcher中的launch方法启动程序

       å†åˆ›å»ºJarLauncher时,父类ExecutableArchiveLauncher找到自己所在的jar,并创建archive

       åœ¨Launcher的launch方法中,通过以上archive的getNestedArchives方法找到/BOOT-INF/lib下所有jar及/BOOT-INF/classes目录所对应的archive,通过这些archives的url生成LaunchedURLClassLoader,并将其设置为线程好橡上下文类加载器,启动应用

       è‡³æ­¤ï¼Œæ‰æ‰§è¡Œæˆ‘们应用程序主入口类的main方法,所有应用程序类文件均可通过/BOOT-INF/classes加载,所有依赖的第三方jar均可通过/BOOT-INF/lib加载

       åœ¨åˆ†æžLaunchedURLClassLoader前,首先了解一下URLStreamHandler

       java中定义了URL的概念,并实现多种URL协议(见URL)*http**file**ftp**jar*等,结合对应的URLConnection可以灵活地获取各种协议下的资源

       å¯¹äºŽjar,每个jar都会对应一个url,如

       jar:file:/data/spring-boot-theory/BOOT-INF/lib/spring-aop-5.0.4.RELEASE.jar!/

       jar中的资源,也会对应一个url,并以'!/'分割,如

       jar:file:/data/spring-boot-theory/BOOT-INF/lib/spring-aop-5.0.4.RELEASE.jar!/org/springframework/aop/SpringProxy.class

       å¯¹äºŽåŽŸå§‹çš„JarFileURL,只支持一个'!/',SpringBoot扩展了此协议,使其支持多个'!/',以实现jarinjar的资源,如

       jar:file:/data/spring-boot-theory.jar!/BOOT-INF/lib/spring-aop-5.0.4.RELEASE.jar!/org/springframework/aop/SpringProxy.class

       è‡ªå®šä¹‰URL的类格式为[pkgs].[protocol].Handler,在运行Launcher的launch方法时调用了JarFile.registerUrlProtocolHandler()以注册自定义的Handler

       åœ¨å¤„理如下URL时,会循环处理'!/'分隔符,从最上层出发,先构造spring-boot-theory.jar的JarFile,再构造spring-aop-5.0.4.RELEASE.jar的JarFile,最后构造指向SpringProxy.class的

       JarURLConnection,通过JarURLConnection的getInputStream方法获取SpringProxy.class内容

       ä»Žä¸€ä¸ªURL,到读取其中的内容,整个过程为

       URLClassLoader可以通过原始的jar协议,加载jar中从class文件

       LaunchedURLClassLoader通过扩展的jar协议,以实现jarinjar这种情况下的class文件加载

       æž„建war包很简单

       æž„建出的war包,其目录机构为

       MANIFEST.MF内容为

       æ­¤æ—¶ï¼Œå¯åŠ¨ç±»å˜ä¸ºäº†org.springframework.boot.loader.WarLauncher,查看WarLauncher实现,其实与JarLauncher并无太大差别

       å·®åˆ«ä»…在于,JarLauncher在构建LauncherURLClassLoader时,会搜索BOOT-INF/classes目录及BOOT-INF/lib目录下jar,WarLauncher在构建LauncherURLClassLoader时,则会搜索WEB-INFO/classes目录及WEB-INFO/lib和WEB-INFO/lib-provided两个目录下的jar

       å¦‚此依赖,构建出的war便支持两种启动方式

       PropretiesLauncher的实现与JarLauncherWarLauncher的实现极为相似,通过PropretiesLauncher可以实现更为轻量的thinjar,其实现方式可自行查阅源码

SpringBoot运行原理

       SpringBoot是一个基于Spring开发,集成了大量第三方库配置的javaweb开发框架

       pom.xml

       çˆ¶ä¾èµ–

       å…¶ä¸­å®ƒä¸»è¦æ˜¯ä¾èµ–一个父项目,主要是管理项目的资源过滤及插件。以后我们导入依赖默认是不需要写版本的。

       å¯åŠ¨å™¨spring-boot-starter

       springboot-boot-starter-xxx:spring-boot的场景启动器郑御

       spring-boot-starter-web:帮我们导入了web模块正常运行所依赖的组件。

       springBoot将所有的功能场景都抽取出来,做成一个个的starter(启动器),只需要在项目中引入这些starter即可,所有相关的依赖都会被引进来,我们要用什么功能就导入什么样的场景启动器即可。

       @SpringBootApplication

       ä½œç”¨ï¼šæ ‡æ³¨åœ¨æŸä¸ªç±»ä¸Šè¯´æ˜Žè¿™ä¸ªç±»æ˜¯SpringBoot的主配置类,SpringBoot运行这个类的main方法来启动SpringBoot应用。

       è¿›å…¥è¿™ä¸ªæ³¨è§£ï¼Œé‡Œé¢åŒ…含了很多其他注解

       @ComponentScan作用:自动扫描并加载符合条件的组件或者bean,将这个bean定义加载到IOC容器中。

       @SpringBootConfiguration作用:SpringBoot的配置类,标注在某个类上,表示这是一个姿咐SpringBoot的配置类。

       è¿›å…¥@SpringBootConfiguration注解查看,这里的@Configuration说明这是一个配置类,配置类对应Spring的xml配置文件。

       ç»§ç»­æŸ¥çœ‹@SpringBootConfiguration包含的其他注解

       @EnableAutoConfiguration:开启自动配置功能

       è¿›å…¥@EnableAutoConfiguration注解查看

       @AutoConfigurationPackage自动配置包

       @import:Spring底层注解@import,给容器中导入一个组件

       @Import({ AutoConfigurationImportSelector.class})给容器导入组件

       AutoConfigurationImportSelector:自动配置导入选择器。那么它导入哪些组件的选择器呢

       è¿™ä¸ªç±»ä¸­æœ‰è¿™æ ·ä¸€ä¸ªæ–¹æ³•ï¼šgetCandidateConfiguration,而在这个方法中有调用了SpringFactoriesLoader类的静态方法loadFactoryNames()方法

       è¿›å…¥loadSpringFactories方法

       æ ¹æ®å…¨å±€æœç´¢Spring.factories,打开后是自动配置的文件。

       éšä¾¿æ‰“开一个其中的自动配置类看,它们都喊册岩是javaConfig配置类,都注入了一些Bean

       æ‰€ä»¥ï¼Œè‡ªåŠ¨é…ç½®çœŸæ­£å®žçŽ°æ˜¯ä»Žclasspath中搜寻所有的META-INF/spring.factories配置文件,并将其中对应的org.springframework.boot.autoconfigure包下的配置项通过反射实例化为对应标注了@Configuration的javaConfig形式的IOC容器配置类,然后将这些都汇总成为一个实例并加载到IOC容器中。

       ç»“论:

       1.SpringBoot在启动的时候从类路径下的META-INF/spring.factories中获取EnableAutoConfiguration指定的值

       2.将这些值作为自动配置类导入容器,自动配置类就生效,帮我们进行自动配置工作。

       3.整个J2EE的整体解决方案和自动配置都在springboot-autoConfigure的jar包中。

       4.它会给容器中导入非常多的自动配置类(xxxAutoConfiguration),就是给容器中导入这个场景需要的所有组件,并配置好这些组件。

       5.有了自动配置类,免去了我们手动编写配置注入功能组件等的工作。

       SpringApplication

       è¿™ä¸ªç±»ä¸»è¦åšäº†ä»¥ä¸‹å››ä»¶äº‹

       1.推断应用的类型是普通的项目还是web项目

       2.查找并加载所有可用初始化器,设置到initializers属性中

       3.找出所有的应用程序监听器,设置到listeners属性中

       4.推断并设置main方法的定义类,找到运行的主类

SpringbootBatch的启动原理-Configuration

       Springboot整合了web和batch,但是他们肯定不是同一条路,在springboot中,会推断当前的运行环境。this.webApplicationType=WebApplicationType.deduceFromClasspath();

       ä»Žä¸Šç¨¿æ¨±æ–‡å¯ä»¥çœ‹å‡ºï¼ŒSpring尝试从classpath里找到特征类,来判断当前app是什么类型。当然这种判断是有局限性的,有可能是transitive带搭渗进来一个带有servlet的类被当成了WebApplicationType.SERVLET,实际上是个WebApplicationType.NONE;。如果不想以web运行就是想运行batch可以在application.properties强行指定WebApplicationType

       å…·ä½“发生作用的请看下面的stacktrace

       å½“一个batchapplication需要启动,需要配置JobRepository,Datasource等等,所有的开始都来自一个annotation@EnableBatchProcessing

       å½“加入@EnableBatchProcessing时,BatchConfigurationSelector开始启动,怎么启动的大家可以键枝丛参考下面的stacktrace。

       import类主要是由ConfigurationClassPostProcessor来实现的。当BatchConfigurationSelector被调用的时候,我们可以看到他有两条支路。

       é‚£ä¹ˆè¿™ä¸¤æ¡è·¯æœ‰å•¥ä¸åŒå‘¢ã€‚主要是job定义的方式不同。

       modular=true的情况下,下面是一个例子

       å¯ä»¥æœ‰å¤šä¸ªå­Ap

SpringBoot源码 | refreshContext方法解析

       本文主要解析SpringBoot启动流程中的`refreshContext`方法。在SpringBoot启动过程中,主要涉及两个阶段:初始化`SpringApplication`对象和`SpringApplication.run`方法执行的内容。`refreshContext`方法的执行,标志着启动流程的深入。

       `refreshContext`方法的主要功能是刷新容器,其源码揭示了这一过程的关键步骤。首先,方法通过调用`refresh`来实现底层`ApplicationContext`的刷新。`ApplicationContext`接口的抽象实现类`AbstractApplicationContext`,通过模板方法设计模式,要求具体子类实现抽象方法,以适应不同的配置存储需求。

       `refresh`方法执行了一系列操作,包括准备刷新上下文、调用上下文注册为bean的工厂处理器、初始化上下文的消息源、初始化特定上下文子类中的其他特殊bean、检查监听器bean并注册,以及发布相应的事件并销毁已经创建的单例及重置active标志。

       在`refresh`方法内部,`prepareRefresh`方法负责准备上下文以进行刷新,包括设置启动日期和活动标志,以及执行属性源的初始化。`obtainFreshBeanFactory`方法获取新的storm 用户画像 源码bean工厂,通过`refreshBeanFactory`方法进行配置,以及`getBeanFactory`方法返回当前上下文的内部bean工厂。

       `prepareBeanFactory`方法配置工厂标准的上下文特征,如上下文类加载器、后置处理器等。`postProcessBeanFactory`方法进一步处理bean工厂,根据WebApplicationType选择特定的操作,如添加后置处理器以及注册特定的web作用域。

       `invokeBeanFactoryPostProcessors`方法调用bean工厂的后置处理器,`registerBeanPostProcessors`方法实例化并注册所有后置处理器bean。`initMessageSource`方法初始化应用上下文消息源,而`initApplicationEventMulticaster`方法则为上下文初始化事件多播。

       `onRefresh`方法执行刷新操作,`createWebServer`方法创建web服务,`registerListeners`方法检查并注册监听器。`finishBeanFactoryInitialization`方法实例化所有剩余的单例bean,而`finishRefresh`方法发布事件,重置Spring核心中的公共内省缓存,标志着容器刷新的结束。

       `resetCommonCaches`方法重置Spring核心中的公共内省缓存,`contextRefresh.end`方法容器刷新结束,最终执行日志打印,完成启动流程。

       总的来说,`refreshContext`方法的执行流程清晰,通过丰富的源码注释,便于学习者深入理解SpringBoot启动机制。本文仅提供方法解析的概览,更多细节请参考原始源码。

头秃了,二十三张图带你从源码了解SpringBoot启动流程!

       源码版本

       作者使用的是Spring Boot的2.4.0版本。不同版本的Spring Boot可能存在差异,建议读者与作者保持一致,以确保源码的一致性。

       从哪入手

       Spring Boot源码的研究起点是主启动类,即标注着`@SpringBootApplication`注解并且包含`main()`方法的类。这是Spring Boot启动的核心。

       源码如何切分

       SpringApplication中的静态`run()`方法是一个复杂的流程,它分为两步:创建`SpringApplication`对象和执行`run()`方法。接下来将分别介绍这两部分。

       如何创建`SpringApplication`

       创建`SpringApplication`的过程本质上是一个对象的生成,通过调试追踪,最终调用的构造方法如图所示。创建过程主要涉及三个阶段,我们将逐一进行深入。

       设置应用类型

       创建过程中的重要步骤是确定应用类型,这将直接影响项目的性质,如Web应用或非Web应用。应用类型由WebApplicationType枚举类决定,加载特定类(如DispatcherServlet)来判断。

       设置初始化器

       初始化器(ApplicationContextInitializer)用于在IOC容器刷新之前进行初始化操作,例如ServletContextApplicationContextInitializer。获取初始化器的方式是从SpringApplication中的方法调用开始的,最终通过`#SpringFactoriesLoader.loadSpringFactories()`方法从类路径加载。

       设置监听器

       监听器(ApplicationListener)负责监听特定的事件(如IOC容器刷新或关闭)。在Spring Boot中,使用SpringApplicationEvent事件来扩展监听器概念,主要在启动过程中触发。获取监听器的方式与初始化器相同,从spring.factories文件中加载。

       总结

       SpringApplication的构建为`run()`方法的执行铺平了道路,关键步骤包括设置应用类型、初始化器和监听器。注意,初始化器和监听器需要在spring.factories文件中声明,才能在构建过程中加载,此时IOC容器尚未创建,即使注入到容器中也不会生效。

       执行`run()`方法

       在构建结束后,到了启动的阶段,`run()`方法将执行一系列操作,分为八个步骤进行详细解析。

       步骤1:获取并启动运行过程监听器

       SpringApplicationRunListener监听器用于监听应用程序的启动过程,通过调用方法从spring.factories文件中获取运行监听器实例,并执行特定事件的广播。

       步骤2:环境构建

       构建过程包括加载系统和自定义配置(如application.properties),并广播事件通知监听器。

       步骤3:创建IOC容器

       执行容器创建过程,根据应用类型选择容器类型,此步骤仅创建容器,未进行其他操作。

       步骤4:IOC容器的前置处理

       这一步是容器刷新前的准备工作,关键操作是将主启动类注入容器,为后续自动化配置奠定基础。

       步骤5:调用初始化器

       执行构建过程中设置的初始化器,加载自定义的初始化器实现。

       步骤6:加载启动类,注入容器

       将主启动类加载到IOC容器中,作为自动配置的入口。

       步骤7:两次事件广播

       这一步涉及两次事件广播,包括ApplicationContextInitializedEvent和ApplicationPreparedEvent。

       步骤8:刷新容器

       容器刷新由Spring框架完成,包括资源初始化、上下文广播器等。

       步骤9:IOC容器的后置处理

       这一步是容器刷新后的扩展操作,通常用于打印结束日志等。

       步骤:发出结束执行的事件

       使用EventPublishingRunListener广播ApplicationStartedEvent事件,允许在IOC容器中注入的监听器响应。

       步骤:执行Runners

       Spring Boot提供了两种Runner,即CommandLineRunner和ApplicationRunner,用于定制额外操作。

       总结

       Spring Boot启动流程相对简洁,通过八个步骤详细描述了从创建到执行的整个过程。理解run()方法的执行流程、事件、初始化器和监听器的执行时间点是关键。

springboot如何启动内置tomcat?(源码详解)

       SpringBoot项目启动时,无需依赖传统Tomcat,因为内部集成了Tomcat功能。本文将深入解析SpringBoot如何通过源码启动内置Tomcat。

       关键点在于`registerBeanPostProcessors`的`onRefresh`方法,它扩展了容器对象和bean实例化过程,确保单例和实例化完成。`initApplicationEventMuliticaster`则注册广播对象,与`applicationEvent`和`applicationListener`紧密相关。

       文章的核心内容集中在`onRefresh()`方法,其中`createWenServer()`是关键。当`servletContext`和`webServer`为空时,会创建并初始化相关的组件,如`servletWebServerFactory`、`servletContext`(Web请求上下文)、`webServer`(抽象的web容器封装)和`WebServer`实例。`getWebServer()`方法允许在Spring容器刷新后连接webServer。

       SpringBoot通过`TomcatServletWebServerFactory`获取webServer,该工厂负责创建和配置webServer,包括Tomcat组件的初始化,如`Connector`和`Context`的设置,以及与wrapper、engine、service和host等的关联。`new Connector`会根据传入的协议进行定制化配置。

       理解了这些扩展点,用户可以自定义配置,通过`ServerProperties`或自定义`tomcatConnectorCustomizers`和`tomcatProtocolHandlerCustomizers`来扩展Tomcat的连接器和协议处理器。这就是SpringBoot设计的巧妙之处。

       最后,SpringBoot的启动流程涉及逐层初始化和启动Tomcat的组件,如engine、context和wrapper,它们通过生命周期方法如`init`、`start`和`destroy`协同工作。启动过程本质上是一个链式调用,每个组件的初始化和启动都会触发下一层组件的逻辑。