spring boot启动和配置加载流程
2020-10-10 10:33:16 0 举报
springboot启动源码跟踪
作者其他创作
大纲/内容
通过条件装配的方式
比如连接池:PooledDataSourceConfiguration
同理配置文件的加载找实现类ConfigFileApplicationListener#postProcessEnvironment
<dependency> <groupId>org.springframework.boot</groupId><artifactId>spring-boot-loader</artifactId> </dependency>
源码分析: SpringBootServletInitializer实现了WebApplicationInitializer接口(这个接口唯一的方法启动容器),
SpringApplication.run(SpringbootApplication.class);
DataSourceAutoConfiguration如何选择数据连接类型
org.springframework.boot.SpringApplication#prepareEnvironment
启动tomcat容器
创建tomcat容器并启动tomcat
Manifest-Version: 1.0Implementation-Title: spring-boot-studyImplementation-Version: 1.0-SNAPSHOTStart-Class: com.study.SpringbootApplicationSpring-Boot-Classes: BOOT-INF/classes//Spring-Boot-Lib: BOOT-INF/lib/Build-Jdk-Spec: 1.8Spring-Boot-Version: 2.1.5.RELEASECreated-By: Maven Archiver 3.4.0Main-Class: org.springframework.boot.loader.JarLauncher
如何实现自动装配
第三方对接
通过@Bean方法bean的方式
WebServer webServer = this.webServer;ServletContext servletContext = getServletContext();
重写configure
第三方插件如何对接springboot
org\\apache\\dubbo\\dubbo-spring-boot-autoconfigure-compatible\\2.7.1\\dubbo-spring-boot-autoconfigure-compatible-2.7.1.jar!\\META-INF\\spring.factories
ConfigurationPropertie的prefix指定前缀s
org.springframework.boot.env.YamlPropertySourceLoader
<properties> <activemq.version>5.15.9</activemq.version> <antlr2.version>2.7.7</antlr2.version> <appengine-sdk.version>1.9.74</appengine-sdk.version>......</properties>
使用上我们只需要引入依赖
里面包含dubbo的容器初始化类(ApplicationContextInitializer),自动配置类(EnableAutoConfiguration),环境后置处理器(EnvironmentPostProcessor),监听器(ApplicationListener)等需要加载的类。
run:反射调用main方法
yaml的加载类:YamlPropertySourceLoader
通过方法bean的方法完成装配DataSource属性
通过自定义一个后置处理器(AnnotationInjectedBeanPostProcessor),在springIOC容器启动过程中,属性注入那次后置处理器调用,调用自定义后置处理器完成spring-dubbo的整合。
指定自动配置类
SpringBootServletInitializer#createRootApplicationContext
war包:外部容器启动
springboot打包,java -jar 通过内部容器启动
run(application);
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.5.RELEASE</version> <relativePath/> </parent>
通过工厂方法bean的方式将服务作为属性注入
@Override protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) { //指定启动类return builder.sources(MyWarSpringbootApplication.class); }
jar包中的MANIFEST.MF
通过方法bean和条件装配来完成。
在配置文件配置相关的配置
比如mybatis需要在启动类上通过@MapperScan指定mapper的路径
启动
只有当DataSource,PooledDataSourceCondition都ok,才会使用连接池
有的直接引用
比如mybatis
@Autowired private DruidDataSourceProperties druidDataSourceProperties;
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId><version>2.1.5.RELEASE</version><relativePath>../../spring-boot-dependencies</relativePath> </parent>
在业务类上注入mapper接口代理对象进行操作
org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext#onRefresh
webServer == null && servletContext == null
因为本次跟踪的是配置文件的加载,因此找实现类ConfigFileApplicationListener#onApplicationEvent
该方法会先判断事件的类型是环境准备事件还是普通事件
还可以通过配置多个方法bean来配置多个数据源
@Import({ AutoConfiguredMapperScannerRegistrar.class })
org.springframework.context.support.AbstractApplicationContext#refresh
调用顺序
直接在YamlPropertySourceLoader的load加上断点,观察调用栈
WebApplicationContext rootAppContext = createRootApplicationContext(\t\t\t\tservletContext);
if (this.environment != null) { return this.environment; } switch (this.webApplicationType) { case SERVLET://标准服务环境 return new StandardServletEnvironment(); case REACTIVE://标准反应网络环境 return new StandardReactiveWebEnvironment(); default://如果不是web服务返回标准环境 return new StandardEnvironment(); }
将属性对象注入
public static void main(String[] args) throws Exception {new JarLauncher().launch(args);}
如果成功初始化数据源和SqlSessionFactory等,MybatisAutoConfiguration才会生效
SpringApplication application = builder.build();
父依赖是spring-boot-dependencies依赖
super.onRefresh(); try { createWebServer(); }
@EnableConfigurationProperties(MybatisProperties.class)
org.springframework.boot.SpringApplication#run(java.lang.String...)
MybatisAutoConfiguration:通过@Configuration标识该类是配置类
org.springframework.context.support.AbstractApplicationContext#onRefresh
构建SqlSessionFactory、SqlSessionTemplate
加载@Configuration修饰的配置类
首先会到缓存取,没有再去加载获取并放到缓存中
@EnableConfigurationProperties(value = DruidDataSourceProperties.class)
mybatis-spring-boot-starter的pom文件引入了mybatis相关的依赖,比如spring-jdbc、mybatis-spring中间件等
环境准备事件:通过环境的后置处理器
ServletWebServerFactory factory = getWebServerFactory();
this.webServer = factory.getWebServer(getSelfInitializer());
其他的一些第三方插件是通过一个自动配置依赖(Xxx-spring-boot-autoconfiguration)和自动配置兼容性依赖(Xxx-spring-boot-autoconfiguration-compatible)两种,如果没有指定就用自动配置依赖下的spring.factories指定的自动配置类进行加载。否则就会使用兼容性的加载各种情况对应的自动配置类,然后通过条件装配来判断最终需要的自动配置类。
Main-Class: org.springframework.boot.loader.JarLauncher
@Import来注册mapper:找到@mapper修饰的类
配置类会先将SqlSessionFactory、DataSource等基础初始化
比如dubbo
类上再通过注解加载指定的属性
org.springframework.boot.loader.PropertiesLauncher#getMainClass
所属包
dubbodubbo-spring-boot-autoconfiguredubbo-spring-boot-starter
@ConfigurationProperties(prefix = \"spring.datasource.druid\")@Datapublic class DruidDataSourceProperties {...}
java -jar调用的主类
ConfigFileApplicationListener.Loader#loadForFileExtension
加载配置文件中已指定前缀配置的属性值
部分依赖不用指定版本号的原因
加载获取属性
org.springframework.boot.env.PropertiesPropertySourceLoader
准备环境,加载配置文件
org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory#getWebServer
org.apache.dubbo核心三个依赖和一个编译依赖
Springboot自动装配基本原理
因为parent依赖没有指定mybatis的版本号,因此需要指定版本
spring-boot-study-1.0-SNAPSHOT.jar\\META-INFMANIFEST.MF文件
org.springframework.boot.context.config.ConfigFileApplicationListener.Loader#loadDocuments
Class<?> mainClass = Thread.currentThread().getContextClassLoader().loadClass(this.mainClassName); Method mainMethod = mainClass.getDeclaredMethod(\"main\
比如mybatis-spring-boot-autoconfigure指向的
pom.xml配置
springboot的parent依赖
会通过SPI(Service Provide Interface)的方式,将相应依赖包下的META-MF读取到的spring.factories中配置的相关配置类加载进来
spring-boot-autoconfigure依赖:spring.factories配置各种三方的自动配置类
ConfigFileApplicationListener#addPropertySources
(WebApplicationContext) application.run();
获取MANIFEST.MF文件中Start-Class指定的启动类
<dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId><version>2.0.0</version></dependency>
listener.onApplicationEvent(event);
依赖包:在对应目录下的spring.factories中指定核心自动配置类
将属性加到环境
比如阿里的Druid
多播器监听事件
autoconfigure依赖来完成与springboot的对接
springboot启动加载配置文件跟踪:
org.springframework.boot.loader.MainMethodRunner#run
内容就是专门指定各类依赖的版本
相关配置通过注解指定配置类
builder = configure(builder);
在启动时,过程中配置启动类
IOC容器启动
@AutoConfigureAfter(DataSourceAutoConfiguration.class)当DataSource初始化后,才会注册MybatisAutoConfiguration
@Bean public DataSource dataSource() throws SQLException { DruidDataSource druidDataSource = new DruidDataSource(); druidDataSource.setUsername(druidDataSourceProperties.getUsername()); druidDataSourceProperties.setPoolPreparedStatements(druidDataSourceProperties.isPoolPreparedStatements()); return druidDataSource; }
指定打包方式:为war<packaging>war</packaging>依赖中排除内部tomcat容器:<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> 编译时依赖,打包会移除内嵌tomcat容器 <scope>provided</scope> </dependency></dependencies>
org.springframework.boot.web.servlet.support.SpringBootServletInitializer#onStartup
加载对应类型的文件获取配置文件中的属性信息
org.springframework.context.event.SimpleApplicationEventMulticaster#invokeListener
获取到了就直接启动
没有自动配置jar的自己写自动配置类
getSelfInitializer().onStartup(servletContext);
指定相关业务项
Springboot的application启动
启动类要extends SpringBootServletInitializer
0 条评论
下一页