springboot 启动源码流程图
2022-03-18 19:10:17 0 举报
springboot 启动流程
作者其他创作
大纲/内容
计时停止
先从 spring.factories查找 缓存有直接返回 在根据 传入 类型 Key Value 查找
根据命令行 实例化 DefaultApplicationArguments 对象
打印启动时间
是否有缓存
启动jar包
@Import(AutoConfigurationImportSelector.class)
@EnableAutoConfiguration注解中属性,获取不需要自动装配的类@SpringBootApplication(exclude = )
ConfigurationClassParser
for (ServletContextInitializer beans : getServletContextInitializerBeans())
是
contextClass = Class.forName(DEFAULT_SERVLET_WEB_CONTEXT_CLASS)
java -jar xx.jar
执行 launch 传入 main 方法主启动类 和 类加载器
通过读取spring.factories 中的OnBeanCondition、OnClassCondition、OnWebApplicationCondition进行过滤
@EnableAutoConfiguration
获取 启动类 mian方法 class 对象
创建简单秒计时
getAttributes(annotationMetadata)
读取完配置类后发送 ApplicationPreparedEvent 事件
这个 ServletWebServerFactory.class 由自动配置类 ServletWebServerFactoryAutoConfiguration @Import 导入
进行设置
@SpringBootApplication
registration.setLoadOnStartup(this.loadOnStartup)
发布 ApplicationStartingEvent 事件
Manifest-Version: 1.0Spring-Boot-Classpath-Index: BOOT-INF/classpath.idxImplementation-Title: spring-rocketmq-demoImplementation-Version: 1.0-SNAPSHOTStart-Class: com.xx.xxAppSpring-Boot-Classes: BOOT-INF/classes/Spring-Boot-Lib: BOOT-INF/lib/Build-Jdk-Spec: 1.8Spring-Boot-Version: 2.3.2.RELEASECreated-By: Maven Jar Plugin 3.2.0Main-Class: org.springframework.boot.loader.JarLauncher
调用实现了AutoConfigurationImportListener 的bean.. 分别把候选的配置名单,和排除的配置名单传进去做扩展
WebApplicationType.deduceFromClasspath()
factory.getWebServer(getSelfInitializer())
核心方法
核心启动方法 运行Spring应用程序,创建并刷新新的ApplicationContext
从 springFactories 文件获取ApplicationContextInitializer.class接口类型 实例
反射调用main方法 执行启动
getConfigurationClassFilter().filter(configurations)
注册 beanDefitnion
return (ConfigurableApplicationContext) BeanUtils.instantiateClass(contextClass)
调用 BeanFactory 处理方法 其中核心扫描 doScan 就在这个方法执行 详细看 spring启动流程源码图
预处理上下文对象
return value 没有的话返回空列表
createApplicationContext()
根据传入类型进行查找, 例如 EnableAutoConfiguration.class
SpringApplication.run(App.class)
根据 加载文件获取的全路径 创建SpringFactories 实例
instanceClass.getDeclaredConstructor(parameterTypes)
获取
getBean 获取 ServletWebServerFactory.class类型 beanNames
tomcat启动后 会回调 this::selfInitialize 函数指针
加入到缓存
调用 getImportGroup 方法 后会调用 process() 方法
创建上下文对象 Spring上下文
获取需要排除的属性
创建类加载器 并且加载 打包到jar包的 所有jar
设置 urlMappping路径
MANIFEST.MF 文件
return instances
模板模式 调用 Servlet 上下文对象 创建 Web服务器
获取构造方法
开始计时 系统当前时间
执行返回所有自动配置类
cache.get(classLoader)
创建实例容器
添加 servlet
refreshContext(context)
((AutoConfigurationImportSelector) deferredImportSelector).getAutoConfigurationEntry(annotationMetadata)
根据classLoader 获取缓存
classLoader.getResources(FACTORIES_RESOURCE_LOCATION)
listeners.running(context);
removeDuplicates(configurations)
初始化
启动自动配置
this.createClassLoader(this.getClassPathArchivesIterator())
MainMethodRunner.run()
获取初始化
获取 DispatcherServletRegistrationBean 实例 进行注册 serlvet
创建 web服务器并返回
创建 Main方法 执行器 传入 启动类 启动参数 类加载器
getSelfInitializer()
this.tomcat.start()
listeners.contextLoaded(context)
jar包中 maven 打包插件 会打入需要的jar包 同时会生成 MANIFEST.MF 文件
传入类型 ApplicationListener.class
new DefaultApplicationArguments(args)
去spring.factroies中读取了SpringApplicationRunListener 的组件, 就是用来发布事件或者运行监听器
执行 new SpringApplication 构造方法使用默认设置自动装配类
return this::selfInitialize
创建并返回 ServletWebServerFactory 实例
通过 new LinkedHashSet(list) 去除重复
传入类型 ApplicationContextInitializer.class
加载配置类 注册BeanDefitnion
指针指向
启动Tomcat
beans.onStartup(servletContext)
return new SpringApplication(primarySources).run(args)
setBaseDir(baseDir.getAbsolutePath())
getImports()
有缓存
创建自动配置 Entry 传入自动配置类和过滤的类
加载 所有引入的jar包的spring.factories文件
return getTomcatWebServer(tomcat)
listeners.started(context)
发布运行事件
onRefresh()
startDaemonAwaitThread()
registration.addMapping(urlMapping)
获取 web 服务器工厂
invokeBeanFactoryPostProcessors(beanFactory)
方法返回
listeners.starting()
initPropertySources()
while 循环加载文件
import导入注解 导入AutoConfigurationImportSelector.class AutoConfigurationImportSelector 实现了 DeferredImportSelector 接口 所以会重写 内部接口 Group的 process()方法
两个核心Main-Class: org.springframework.boot.loader.JarLauncher 启动项目打包成jar包的加载器使用 -jar 参数时,后面的参数是的 jar文件名 会去 MANIFEST.MF 找 Main-Class: springboot提供启动类Java没有提供任何标准的方式来加载嵌套的jar文件 所以提供了 JarLauncher Start-Class: com.xx.xxApp 自己java代码的springboot 启动类 会在 JarLauncher 中调用
获取class 对象
UrlResource resource = new UrlResource(url
refresh()
deduceMainApplicationClass()
设置基本路径
直接扫描 doScan 发现所有注解 解析配置类
核心方法 从 META-INF/spring.factories 中获得自动配置类 启动的时候缓存已经缓存过 可以直接获取
执行 launch
new Tomcat()
printBanner(environment)
getSpringFactoriesInstances(ApplicationListener.class))
发布启动事件
getRunListeners(args);
阻塞
调用 onStartup方法
配置解析类 getImports() 方法
.run(args)
return result
List<T> instances = new ArrayList<>(names.size())
初始化环境变量 读取配置文件信息(基于监听器)
对当前组的 bena进行排序
打印 springboot Log 官网称这叫横幅
添加
反射实例化 加入到实例容器
this.group.selectImports()
解析后 注册到 BeanDefitninMaps
注册 servlet
TomcatWebServer.this.tomcat.getServer().await()
设置启动时加载顺序值(负值表示第一次调用时加载)
createWebServer()
执行完 process() 调用 .selectImports()
设置守护并阻塞线程
刷新容器 spring容器核心方法
创建实例化 并返回
刷新容器 spring 核心
Spring.factories 文件读取容器
stopWatch.stop()
getBeanFactory().getBeanNamesForType(ServletWebServerFactory.class)
发布事件
stopWatch.start()
创建 TomcatWebServer 默认端口 8080
执行run方法
getWebServerFactory
创建服务器
springboot启动类注解
有三个实现类 Jetty Tomcat Undertow 以tomcat 为例
configure(registration)
去除排除的类
initialize()
返回列表
函数指针指向了 selfInitialize 方法
根据上面设置的 类型(大部分是servelet 创建上下文class 对象)
getSpringFactoriesLoaderFactoryClass() 传入的类型是 EnableAutoConfiguration.class
new StopWatch()
getSpringFactoriesInstances(ApplicationContextInitializer.class))
(new JarLauncher()).launch(args)
0 条评论
下一页