Spring Boot 笔记

起步依赖

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。如果有自定义配置,可在配置文件中配置:

  1. application.properties
  2. 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 种方式:

  1. @Value:修饰成员变量,使用@Value("${str1}")@Value("${person.name}")

  2. Environment:使用 @Autowired 引入Environment变量,使用它获取配置文件中的变量。在一次获取多个配置项的场景下,Environment的比@Value方便。

    @RestController
    public class Demo01_HelloWorldController {
        @Autowired
        private Environment env;
    
        @RequestMapping("/hello")
        public String hello() {
            return env.getProperty("helloWorld");
        }
    }
    
  3. @ConfigurationProperties:给一个类加@ConfigurationProperties修饰,类的成员变量与配置文件中的配置项名称一致时,成员变量会被赋值。@ConfigurationProperties还可指定prefix前缀,更容易查找到配置项。

    @Component
    @ConfigurationProperties(prefix = "person")
    @Data
    public class Person {
        private String name;
        private int age;
    }
    

profile

  1. profile 用来完成不同环境下,动态切换配置的功能

  2. profile 的配置方式:

    1. 多 profile 文件方式:提供多个配置文件,每个文件代表一种环境。官方指定格式:applications-${profile}.properties/yml

      • application.properties/yml:公共配置项,本地可在此配置spring.profiles.active=dev

      • application-dev.properties/yml:开发环境

      • application-test.properties/yml :测试环境

      • application-prod.properties/yml :生产环境

    2. yml 多文档方式:

      • 在 yml 中使用 --- 分隔不同环境配置
  3. @Profile:使用@Profile注解指定 bean 在特定的 profile 环境中生效,比如定义一个 bean 只在开发环境中激活:

    @Component
    @Profile("dev")
    public class DevBean
    
  4. profile 激活方式:

    • 配置文件:在配置文件中配置 spring.profiles.active=dev
    • 虚拟机参数:比如在 Idea 的 VM options 指定:Dspring.profiles.active=dev
    • 命令行参数:java -jar xxx.jar -- spring.profiles.active=dev

内部配置加载顺序

Spring Boot 程序启动时,会先后从一下几个位置加载配置文件:

  1. file:./config/ 当前项目的/config目录下。
  2. file:./ 当前项目的根目录
  3. classpath:/config/ classpath 的/config目录。classpath 路径对应 resources 目录。
  4. 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 的功能就是可以根据条件来判断是否要初始化这个类。

一、自定义条件步骤:

  1. 定义条件类:自定义类实现Condition接口,重写matches方法,在matches方法中进行逻辑判断,返回boolean值。matches方法的两个参数:

    • context:上下文对象,可获取属性值、类加载器、BeanFactory
    • metadata:元数据对象,用于获取注解属性
    @FunctionalInterface
    public interface Condition {
    	boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata);
    
    }
    
  2. 判断条件:在初始化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中的事件监听机制定义了以下几个角色:

  1. 事件:Event,继承java.util.EventObject的对象
  2. 事件源:Source,任意对象Object
  3. 监听器:Listener,实现java.util.EventListener接口的对象

Spring Boot 监听机制

Spring Boot 在项目启动时,会对几个监听器进行回调,我们可以实现这些监听器接口,在项目启动时完成这些操作。

  • ApplicationContextlnitializer
  • SpringApplicationRunListener
  • CommandLineRunner
  • ApplicationRunner

CommandLineRunnerApplicationRunner类似,都是在 IOC 容器加载完成后再执行的。ApplicationContextlnitializerSpringApplicationRunListener基于 SPI 机制,需要再resources 目录下创建MTA-INF目录,再在spring.properties文件中申明自定义的初始化器。

这些监听器与之对应的事件,都是SpringApplicationEvent的子类,最终继承的是java.util.EventObject

actuator 监控

Spring Boot 自带监控功能 Actuator,可以帮助实现对程序内部运行情况监控,比如监控状况、Bean 加载情况、配置属性
、日志信息等。

打 war 包

posted @ 2023-07-12 18:33  xfcoding  阅读(32)  评论(0编辑  收藏  举报