springboot启动原理

一句话#

springboot在启动时除了spring context容器启动的流程,还加入了通过spi实现的根据依赖自动装配的机制。
springboot容器启动的流程,先初始化事件监听器,加载环境信息,创建applicationContext容器,执行applicationInitializer的initialize方法,在容器refresh时,会通过spi机制获取到所有的autoConfiguration类(解析spring.factotries文件)并加载配置类中相关bean注入context容器,完成自动装配。

细分原理#

应用启动,容器初始化#

1、通过spi加载所有的springApplicationRunListener,在后续各个启动步骤中发消息
2、创建环境Environment,加载属性文件配置、加载命令行参数等启动时所需的配置信息
3、创建ApplicationContext,将环境Environment设置给context
4、通过spi加载所有的applicationInitializer并调用其initialize方法
5、【核心】将spi拿到的EnableAutoConfiguration配置类的所有bean加载到已创建好的ioc容器
6、调用applicationContext的refresh方法,完成ioc容器可用

问题1:创建的环境Environment里都有什么?
加载属性文件配置、加载命令行参数等启动时所需的配置信息

问题2:spi拿到全部EnableAutoConfiguration类的具体入口?
refreshContext方法,bean实例化之前,执行AutoConfigurationImportSelector的selectImports方法,返回要实例化的类信息列表。

问题3:applicationContext的refresh方法主要逻辑?
初始化环境、设置类加载器 -> 解析加载BeanDefinition对象(应该是这里拿到的全部的EnableAutoConfiguration类) -> 将BeanDefinition对象注册到BeanFactory -> 实例化非懒加载的单例Bean -> 注册所有BeanPostProcessor到BeanFactory中 -> 初始化剩余非懒加载的Bean初始化 -> 完成刷新操作,发布容器事件 -> 返回刷新后的BeanFactory

自动装配#

SPI(service provider interface), 定义接口后,通过读取文件配置的方式加载实现类。
关键注解:@EnableAutoConfiguration, 借助@Import,SpringFactoriesLoader, 把所有spring.factories文件配置的@Configuration配置类找到并实例化,将其中bean加载到ioc容器,即实现了自动装配。

pageHelper-springboot

springboot Mybatis 数据库分页获取 ,使用pageHelper插件

maven

1
2
3
4
5
6
<!--pagehelper-->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.1.1</version>
</dependency>

引用此依赖可能会与其它springboot依赖冲突,此时可手动去除其它依赖

1
2
3
4
compile ('com.github.pagehelper:pagehelper-spring-boot-starter:1.2.5') {
exclude group: 'org.springframework.boot', module: ''
exclude group: 'org.mybatis.spring.boot', module: ''
}

application.properties

1
2
3
4
5
#pagehelper分页插件配置
pagehelper.helperDialect=mysql
pagehelper.reasonable=true
pagehelper.supportMethodsArguments=true
pagehelper.params=count=countSql

调用

1
2
PageHelper.startPage(pageNum, pageSize);
mapper.loadAll();

springboot文档阅读 第三章 配置信息读取

稍微粘贴一下配置文件信息,但还是没有总结出最佳实践,todo待总结,不过想必是spring源码的配置方式吧。

判断环境是否是web环境

SpringApplication将尝试为你创建正确类型的ApplicationContext,默认情况下,根据你开发的是否为web应用决定使用AnnotationConfigApplicationContextAnnotationConfigEmbeddedWebApplicationContext

用于确定是否为web环境的算法相当简单(判断是否存在某些类),你可以使用setWebEnvironment(boolean webEnvironment)覆盖默认行为。

springboot文档阅读 第二章 继承parent与远程调试

继承 starter parent ?

继承的话:

如果你想配置项目,让其继承自spring-boot-starter-parent,只需将parent按如下设置:

1
2
3
4
5
6
<!-- Inherit defaults from Spring Boot -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.1.BUILD-SNAPSHOT</version>
</parent>

:你应该只需在该依赖上指定Spring Boot版本,如果导入其他的starters,放心的省略版本号好了。

按照以上设置,你可以在自己的项目中通过覆盖属性来覆盖个别的依赖。例如,你可以将以下设置添加到pom.xml中来升级Spring Data到另一个发布版本。

1
2
3
<properties>
<spring-data-releasetrain.version>Fowler-SR2</spring-data-releasetrain.version>
</properties>

查看spring-boot-dependencies pom获取支持的属性列表。

spring-boot-starter-parent选择了相当保守的Java兼容策略,如果你遵循我们的建议,使用最新的Java版本,可以添加一个java.version属性:

1
2
3
<properties>
<java.version>1.8</java.version>
</properties>

Spring Boot包含一个[Maven插件](../VIII. Build tool plugins/58. Spring Boot Maven plugin.md),它可以将项目打包成一个可执行jar。如果想使用它,你可以将该插件添加到<plugins>节点处:

1
2
3
4
5
6
7
8
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>

:如果使用Spring Boot starter parent pom,你只需添加该插件而无需配置它,除非你想改变定义在partent中的设置。

springboot文档阅读 第一章

@RestController和@RequestMapping

Example类上使用的第一个注解是@RestController,这被称为构造型(stereotype)注解。它为阅读代码的人提供暗示(这是一个支持REST的控制器),对于Spring,该类扮演了一个特殊角色。在本示例中,我们的类是一个web @Controller,所以当web请求进来时,Spring会考虑是否使用它来处理。

@RequestMapping注解提供路由信息,它告诉Spring任何来自”/“路径的HTTP请求都应该被映射到home方法。@RestController注解告诉Spring以字符串的形式渲染结果,并直接返回给调用者。

@RestController@RequestMapping是Spring MVC中的注解(它们不是Spring Boot的特定部分),具体参考Spring文档的MVC章节

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×