起步依赖
Spring Boot 默认导入父工程依赖spring-boot-starter-parent
,它里面已经申明好了众多的可能会用到的依赖。比如常用的spring-boot-starter-web
,我们需要用什么,就在自己的pom.xml
文件中定义就好了。
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.12</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
spring-boot-starter-parent
点进去看会发现所有依赖申明在spring-boot-dependencies
这个pom
文件中申明的。
配置文件分类
Spring Boot 基于约定的,很多配置有默认值。比如 tomcat 端口号默认为8080。如果有自定义配置,可在配置文件中配置:
- application.properties
- application.yml
YAML 语法
yaml 文件的扩展名可以为.yml
或.yaml
。
- 相同缩进代表一个层级
- 缩进不允许使用 tab 键,只允许用空格
- 缩进的空格数不重要,只用相同层级左侧对齐即可
- 冒号后面有一个空格
- 大小写敏感
YAML 数据格式
-
对象:键值对集合
person: name: zhangsan
-
数组
address: - Beijing - Shanghai # 行内写法 address: [Beijing,Shanghai]
-
单个变量
str1: 'hello \n world' # 单引号忽略转义字符 str2: "hello \n world" # 双引号识别转移字符
-
参数引用
name: abc person: name: ${name} # 引用上面定义的name值
读取配置文件的内容
3 种方式:
-
@Value
:修饰成员变量,使用@Value("${str1}")
、@Value("${person.name}")
-
Environment
:使用@Autowired
引入Environment
变量,使用它获取配置文件中的变量。在一次获取多个配置项的场景下,Environment
的比@Value
方便。@RestController public class Demo01_HelloWorldController { @Autowired private Environment env; @RequestMapping("/hello") public String hello() { return env.getProperty("helloWorld"); } }
-
@ConfigurationProperties
:给一个类加@ConfigurationProperties
修饰,类的成员变量与配置文件中的配置项名称一致时,成员变量会被赋值。@ConfigurationProperties
还可指定prefix
前缀,更容易查找到配置项。@Component @ConfigurationProperties(prefix = "person") @Data public class Person { private String name; private int age; }
profile
-
profile 用来完成不同环境下,动态切换配置的功能
-
profile 的配置方式:
-
多 profile 文件方式:提供多个配置文件,每个文件代表一种环境。官方指定格式:
applications-${profile}.properties/yml
。-
application.properties/yml
:公共配置项,本地可在此配置spring.profiles.active=dev
-
application-dev.properties/yml
:开发环境 -
application-test.properties/yml
:测试环境 -
application-prod.properties/yml
:生产环境
-
-
yml 多文档方式:
- 在 yml 中使用
---
分隔不同环境配置
- 在 yml 中使用
-
-
@Profile
:使用@Profile
注解指定 bean 在特定的 profile 环境中生效,比如定义一个 bean 只在开发环境中激活:@Component @Profile("dev") public class DevBean
-
profile 激活方式:
- 配置文件:在配置文件中配置
spring.profiles.active=dev
- 虚拟机参数:比如在 Idea 的 VM options 指定:
Dspring.profiles.active=dev
- 命令行参数:
java -jar xxx.jar -- spring.profiles.active=dev
- 配置文件:在配置文件中配置
内部配置加载顺序
Spring Boot 程序启动时,会先后从一下几个位置加载配置文件:
file:./config/
当前项目的/config
目录下。file:./
当前项目的根目录classpath:/config/
classpath 的/config
目录。classpath 路径对应 resources 目录。classpath:/
classpath 的根目录
高优先级配置的属性会生效。项目是模块的父目录。打包时还是以当前 maven 工程的为基准。也就是说一般情况下,使用3、4两种配置方式。
外部配置加载顺序
方式之一就是可以使用命令行,在运行jar包的时候修改配置项的值,比如:java -jar xxx.jar --server.port=8081
。
Spring Boot 整合其他框架
JUnit
@SpringBootTest(classes = Application.class)
public class ApplicationTests {
@Autowired
private UserService userService;
@Test
void testUserService() {
userService.getName();
}
}
如果测试类的包层级跟源码包层级一致或者是子包,@SpringBootTest
无需指定classes = 启动类
了。
Spring Boot 自动配置
Condition
思考:Spring Boot 种很多类我拿来即用,它是什么时候初始化的呢?Spring Boot 怎么直到要帮我们初始化这个类呢?
Condition 的功能就是可以根据条件来判断是否要初始化这个类。
一、自定义条件步骤:
-
定义条件类:自定义类实现
Condition
接口,重写matches
方法,在matches
方法中进行逻辑判断,返回boolean
值。matches
方法的两个参数:context
:上下文对象,可获取属性值、类加载器、BeanFactory
等metadata
:元数据对象,用于获取注解属性
@FunctionalInterface public interface Condition { boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata); }
-
判断条件:在初始化
Bean
时,使用@Conditional(条件类.class)
注解
二、Spring Boot 提供的常用条件注解:
@ConditionalOnProperty
:如果有指定的配置,条件生效;@ConditionalOnBean
:如果有指定的Bean,条件生效;@ConditionalOnMissingBean
:如果没有指定的Bean,条件生效;@ConditionalOnMissingClass
:如果没有指定的Class,条件生效;@ConditionalOnWebApplication
:在Web环境中条件生效;@ConditionalOnExpression
:根据表达式判断条件是否生效。
@Component
@ConditionalOnProperty(value = "person.name", havingValue = "zhangsan")
public class AwsStorageService implements StorageService {
...
}
Enable 注解原理
@Enable* 底层依赖于@Import
注解导入一些类,使用@Import
导入的类会被 Spring 加载到 IOC 容器中。@Import
提供4中用法:
① 导入 Bean
② 导入配置类
③ 导入ImportSelector
实现类。一般用于加载配置文件中的类
④ 导入ImportBeanDefinitionRegistrar
实现类。
@EnableAutoConfiguration 注解原理
@EnableAutoConfiguration
注解内部使用@Import(AutoConfigurationImportSelector.class)
来加载配置类。- 配置文件位置:
META-INF/spring.factories
,该配置文件中定义了大量的配置类,当 Spring Boot 应用启动时,会自动加载这些配置类,初始化Bean - 并不是所有的Bean都会被初始化,在配置类中使用
Condition
来加载满足条件的 Bean
自定义 starter
...
Spring Boot 监听机制
Java 监听机制
Spring Boot 的监听机制,其实是对 Java 提供的事件监听机制的封装。Java中的事件监听机制定义了以下几个角色:
- 事件:
Event
,继承java.util.EventObject
的对象 - 事件源:
Source
,任意对象Object
- 监听器:
Listener
,实现java.util.EventListener
接口的对象
Spring Boot 监听机制
Spring Boot 在项目启动时,会对几个监听器进行回调,我们可以实现这些监听器接口,在项目启动时完成这些操作。
ApplicationContextlnitializer
SpringApplicationRunListener
CommandLineRunner
ApplicationRunner
CommandLineRunner
和ApplicationRunner
类似,都是在 IOC 容器加载完成后再执行的。ApplicationContextlnitializer
和SpringApplicationRunListener
基于 SPI 机制,需要再resources 目录下创建MTA-INF
目录,再在spring.properties
文件中申明自定义的初始化器。
这些监听器与之对应的事件,都是SpringApplicationEvent
的子类,最终继承的是java.util.EventObject
。
actuator 监控
Spring Boot 自带监控功能 Actuator,可以帮助实现对程序内部运行情况监控,比如监控状况、Bean 加载情况、配置属性
、日志信息等。