课程地址:www.bilibili.com/video/BV1Lq…
SpringBoot概述
Springboot提供了一种快速使用Spring的方式,基于约定优于配置的思想(简化spring的开发)
- Spring的缺点:配置繁琐、依赖繁琐;
- Springboot功能:1. 自动配置;2. 起步依赖(将具有某些功能的依赖打成包引用)3. 辅助功能。
SpringBoot快速入门
实现步骤:
- 创建Maven项目;
- 导入Springboot起步依赖;
- 定义Controller;
- 编写引导类:xxxApplication;
- 启动测试。
SpringBoot在创建时使用jar包的打包方式,可以通过Java -jar直接运行。 详见->
面试官:说说SpringBoot为什么可以使用Jar包启动?
SpringBoot起步依赖原理分析
- spring-boot-starter-parent:定义了各种依赖的版本信息,组合了一套最优搭配的依赖版本;
- spring-boot-starter-web:web开发依赖jar包的集合。
我们的工程继承parent,引入starter后,通过依赖传递,就可以获得需要的jar包,且不会存在版本冲突问题!
SpringBoot配置-配置文件分类
SpringBoot是基于约定的,很多配置都有默认值,如果想替换默认配置,就可以使用application.properties 或 application.yml(application.yaml)进行配置。
- properties
server.port=8001
- yml
server:
port:_8001 # _代表空格
配置生效优先级:prperties > yml > yaml
SpringBoot配置-yaml
yaml是一种直观的能被识别的数据序列化格式,容易和脚本语言交互。yaml以数据为核心的,比传统的xml方式更加简洁。
yaml基本语法
- 大小写敏感;
- 数据值前边必须有空格,作为分隔符;
- 使用缩进标识层级关系;
- 缩进时不允许使用Tab键,只允许使用空格;(IDEA默认Tab4个空格)
- 缩进的空格数目不重要,只要相同层级的元素左对齐即可;
- #标识注释,注释掉一行。
yaml数据格式
- 对象(map):键值对的集合
person:
name: zhangsan
# 行内写法
person: {name: zhangsan}
- 数组:一组按次序排列的值
address:
- beijing
- shanghai
# 行内写法
address: [beijing,shanghai]
- 纯量:单个的、不可再分的值
msg1: 'hello \n word' # 单引忽略转义字符
msg2: "hello \n word" # 双引识别转义字符
- 参数引用
name: lisi
person:
name: ${name} # 引用上边定义的name值
SpringBoot配置-读取配置文件内容
- @Value
@Value("${person.name}")
private String name;
- Environment
@Autowired
private Environment env;
env.getProperty("person.name") // 代码中使用
- @ConfigurationProperties
常用场景1:
@Configuration
@ConfigurationProperties(prefix = "promocore.thread.pool")
public class ThreadPoolConfig {
private String corePoolSize = "default_pool:10"; // Map更合理
private String maxPoolSize = "default_pool:30";
private String queueCapacity = "default_pool:200";
}
对应的配置文件如下:
sbt.thread.pool.corePoolSize=client_component:60;service_component:30;timeout_callback:30;high_concurrency:60;default_pool:60
在此种场景下,当Bean被实例化时,@ConfigurationProperties会将对应前缀的后面的属性与Bean对象的属性匹配,符合条件则进行赋值。
常用场景2:
@Configuration
public class DataSourceConfig {
@Primary
@Bean(name = "primaryDataSource")
@ConfigurationProperties(prefix="spring.datasource.primary")
public DataSource primaryDataSource() {
return DataSourceBuilder.create().build();
}
}
@Configuration注解的配置类中,通过@Bean注解在某个方法上将方法返回的对象定义为一个Bean,并使用配置文件中相应的属性初始化该Bean的属性。
SpringBoot配置-profile
profile是用来完成不同环境下配置动态切换的。通常同一套代码会被部署到不同环境,比如:开发、测试和生产,其中数据库地址、服务端口等配置各不相同,如果每次打包时,都需要修改配置文件,将非常麻烦。
- profile配置方式
- 多profile文件方式(application-dev.yml、application-test.yml和application-prd.yml)
- yml多文档方式(一个yml存在dev、test和prd三个环境的配置,使用---分隔)
- profile激活方式
- 配置文件,在配置文件中配置:spring.profiles.active=dev;
- 虚拟机参数,在VM options指定:-Dspring.profiles.active=dev;
- 命令行参数:java -jar sbt.jar --spring.profiles.active=dev。
SpringBoot配置-内部配置文件加载顺序
SpringBoot程序启动时,会从以下位置加载配置文件:
- 当前项目下的/config目录下: file:./config/
- 当前项目的根目录: file:./
- classpath的/config目录: classpath:/config/
- classpath的根目录: classpath:/
SpringBoot配置-外部配置加载顺序
- 通过命令行:java -jar xxx.jar --server.port=8001
- 外部配置文件:java -jar xxx.jar --spring.config.location=${filePath}
SpringBoot整合Junit
实现步骤:
- 引入starter-test起步依赖;
- 编写测试类;
- 添加测试相关注解:@SpringBootTest(classes = 启动类.class);
- 编写测试方法。
@RunWith(SpringRunner.class)
@SpringBootTest(classes = SbtAppApplication.class)
public class UserServiceTest {
@Autowired
private UserService userService;
@Test
public void test(){
userService.sayHello();
}
}
SpringBoot整合redis
实现步骤:
- 引入redis起步依赖;
- 配置redis相关属性;
- 注入redisTemplate模板;
- 编写测试方法,测试。
@RunWith(SpringRunner.class)
@SpringBootTest(classes = SbtAppApplication.class)
public class UserServiceTest {
@Autowired
private RedisTemplate<String, String> redisTemplate;
@Test
public void set() {
redisTemplate.opsForValue().set("sbt", "laowang");
}
@Test
public void get() {
String value = redisTemplate.opsForValue().get("sbt");
System.out.println(value);
}
}
SpringBoot整合Mybatis
实现步骤:
- 引入mybatis起步依赖,添加mySQL驱动;
- 编写DataSource和mybatis相关配置;
- 定义表和实体类;
- 编写dao和mapper文件/纯注解开发;
- 测试。
使用mybatis-generator插件自动生成后,加入以下配置:
#mysql配置
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/ambassador
spring.datasource.username=root
spring.datasource.password=789456
#mybatis配置
#mybatis类别名配置
mybatis.type-aliases-package=com.balloon.sbtapp.dao.entity
#指定mybatis配置文件
mybatis.config-location=classpath:mybatis-config.xml
#mapper映射文件路径
mybatis.mapper-locations=classpath:mybatis/mappers/*.xml
详细配置参见:springboot整合mybatis mapper扫描问题
SpringBoot自动配置-Condition
Condition是在Spring4.0增加的条件判断功能,通过这个可以选择性的创建bean对象。
思考:Springboot是如何知道要创建哪个Bean的?比如Springboot是如何知道要创建RedisTemplate的?
SpringBoot提供的常用条件注解:
- @ConditionalOnProperty:判断配置文件中是否有对应的属性和值才初始化Bean;
- @ConditionalOnClass:判断环境中是否有对应字节码文件才初始化Bean;
- @ConditionalOnMissingBean:判断环境中没有对应的Bean才初始化Bean。
代码参见:org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration
SpringBoot自动配置-切换web服务器
实现步骤:
- 排除SpingBoot中自带的tomcat
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
- 添加undertow web服务依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-undertow</artifactId>
</dependency>
代码参见:org.springframework.boot.autoconfigure.web.embedded.EmbeddedWebServerFactoryCustomizerAutoConfiguration
SpringBoot自动配置-Enable注解原理
SpringBoot中提供了很多Enable开头的注解,这些注解都是用于动态启用某些功能的,而底层原理是使用@Import注解导入一些配置类,实现Bean的动态加载。
思考:Springboot工程是否可以直接获取jar包中定义的Bean? -- 不会
@Enable*注解:底层依赖于@Import注解导入一些类,@Import导入的类会被spring加载到IOC容器中。 @Import提供4种用法:
- 导入Bean;
- 导入配置类;
- 导入ImportSelector实现类,一般用于加载配置文件中的类;
- 导入ImportBeanDefinitionRegistrar实现类。
代码参见:@SpringBootApplication -> @EnableAutoConfiguration -> @Import(AutoConfigurationImportSelector.class)
SpringBoot自动配置-EnableAutoConfiguration注解
- @EnableAutoConfiguration注解内部使用@Import(AutoConfigurationImportSelector.class)来加载配置类;
- 配置文件位置:META-INF/spring.factories,该配置文件中定义了大量的配置类,当SpringBoot启动时,会自动加载这些配置类,初始化Bean;
- 并不是所有的Bean都会被初始化,在配置类中使用Condition来加载满足条件的Bean。
代码参见:@SpringBootApplication -> @EnableAutoConfiguration -> @Import(AutoConfigurationImportSelector.class) -> AutoConfigurationImportSelector#selectImports#getAutoConfigurationEntry#getCandidateConfigurations -> META-INF/spring.factories -> RedisAutoConfiguration -> @ConditionalOnClass({RedisOperations.class})
SpringBoot自动配置-自定义starter实现
思考:自定义redis-starter,要求当导入redis坐标时,SpringBoot自动创建Jedis的Bean?
实现步骤:
- 创建redis-spring-boot-autoconfigure模块;
- 创建redis-spring-boot-starter模块,依赖redis-spring-boot-autoconfigure的模块;
- 在redis-spring-boot-autoconfigure模块中初始化Jedis的Bean,并定义META-INF/spring.factories文件;
- 在测试模块中引入自定义的redis-starter依赖,测试获取Jedis的Bean,操作Redis。
SpringBoot事件监听
Java监听机制
SpringBoot的监听机制,其实是对Java的事件监听机制的封装。 Java的时间监听机制定义了以下几个角色:
- 事件:Event,继承java.util.EventObject类的对象;
- 事件源:Source,任意对象Object;
- 监听器:Listener,实现java.util.EventListener接口的对象。
SpringBoot监听机制
SpringBoot在项目启动时,会对几个监听器进行回调,我们可以实现这些监听器接口,在项目启动时完成一些操作。 ApplicationContextInitializer、SpringApplicationRunListener、CommandLineRunner、Applicationrunner。
SpringBoot启动流程分析
orz:# spring核心之Bean加载过程剖析 # 教你如何实现自定义SpringBootStarter
SpringBoot监控
SpringBoot自带监控功能Actuator,可以帮助实现对程序内部运行情况监控,比如监控状况、Bean加载情况、配置熟悉、日志信息等。
使用步骤:
- 导入依赖坐标
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
Spring Boot Admin
- Spring Boot Admin是一个开源社区项目,用于管理和监控SpringBoot应用程序;
- Spring Boot Admin 有两个角色,客户端(Client)和服务端(Server);
- 应用程序作为Spring Boot Admin Client向为Spring Boot Admin Server注册;
- Spring Boot Admin Server 的UI界面将Spring Boot Admin Client的Actuator Endpoint上的一些监控信息。
实现步骤如下:
admin-server
- 创建 admin-server 模块;
- 导入依赖坐标 admin-starter-server;
- 在引导类上启用监控功能@EnableAdminServer;
admin-client
- 创建 admin-client 模块;
- 导入依赖坐标 admin-starter-client;
- 配置相关信息:server地址等;
- 启动server和client服务,访问server。
SpringBoot项目部署
SpringBoot项目开发完毕后,支持两种方式部署到服务器:
- jar包:官方推荐
- war包