• 「SpringBoot」08 高级特性


    SpringBoot——高级特性

    笔记整理自【尚硅谷】雷神SpringBoot2视频教程

    1. Profile功能

    为了方便多环境适配,SpringBoot简化了profile功能。

    Ⅰ. application-profile功能

    • 默认配置文件application.yaml任何时候都会加载。

    • 指定环境配置文件application-{env}.yaml

      application-test.yaml

      person:
        name: test-张三
      server:
        port: 7000
      
      • 1
      • 2
      • 3
      • 4

      application-prod.yaml

      person:
        name: prod-张三
      server:
        port: 8000
      
      • 1
      • 2
      • 3
      • 4
    • 激活指定环境

      ➢ 配置文件激活

      application.properties

      # 激活prod配置文件(指定激活的环境,默认配置文件和指定环境的配置文件都会生效)
      spring.profiles.active=prod
      
      • 1
      • 2

      ➢ 命令行激活:java -jar xxx.jar --spring.profiles.active=prod --person.name=haha

      ​ ◽️ 修改配置文件的任意值,命令行优先

    • 默认配置与环境配置同时生效

    • 同名配置项,profile配置优先

    Ⅱ. @Profile条件装配功能

    public interface Person {
    
       String getName();
       Integer getAge();
    
    }
    
    @Profile("test") // 加载application-test.yaml里的
    @Component
    @ConfigurationProperties("person")
    @Data
    public class Worker implements Person {
    
        private String name;
        private Integer age;
    }
    
    @Profile(value = {"prod", "default"}) // 加载application-prod.yaml里的
    @Component
    @ConfigurationProperties("person")
    @Data
    public class Boss implements Person {
    
        private String name;
        private Integer age;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    Controller

    @RestController
    public class HelloController {
        
        @Autowired
        private Person person;
        
        @GetMapping("/")
        public String hello() {
            return person.getClass().toString();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    @Profile还可以修饰在方法上

    class Color {
    }
    
    @Configuration
    public class MyConfig {
    
        @Profile("prod") // 标志在方法上 指定的环境 这个方法组件才生效
        @Bean
        public Color red() {
            return new Color();
        }
    
        @Profile("test")
        @Bean
        public Color green() {
            return new Color();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    Ⅲ. Profile分组

    spring.profiles.active=production
    
    spring.profiles.group.production[0]=proddb
    spring.profiles.group.production[1]=prodmq
    
    # 使用:--spring.profiles.active=production 激活
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    2. 外部化配置

    官方文档 - Externalized Configuration

    Spring Boot使用一个非常特殊的PropertySource顺序,该顺序旨在允许合理地重写值。属性按以下顺序考虑(较低项的值优先于较早项的值):

    1. Default properties (specified by setting SpringApplication.setDefaultProperties).
    2. @PropertySource annotations on your @Configuration classes. Please note that such property sources are not added to the Environment until the application context is being refreshed. This is too late to configure certain properties such as logging.* and spring.main.* which are read before refresh begins.
    3. Config data (such as application.properties files)
    4. A RandomValuePropertySource that has properties only in random.*.
    5. OS environment variables.
    6. Java System properties (System.getProperties()).
    7. JNDI attributes from java:comp/env.
    8. ServletContext init parameters.
    9. ServletConfig init parameters.
    10. Properties from SPRING_APPLICATION_JSON (inline JSON embedded in an environment variable or system property).
    11. Command line arguments.
    12. properties attribute on your tests. Available on @SpringBootTest and the test annotations for testing a particular slice of your application.
    13. @TestPropertySource annotations on your tests.
    14. Devtools global settings properties in the $HOME/.config/spring-boot directory when devtools is active.

    为了提供一个具体示例,假设您开发了一个使用name属性的@组件,如以下示例所示:

    import org.springframework.stereotype.*;
    import org.springframework.beans.factory.annotation.*;
    
    @Component
    public class MyBean {
    
        @Value("${name}")
        private String name;
    
        // ...
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    Ⅰ. 外部配置源

    Spring Boot允许您将配置外部化,以便您可以在不同的环境中使用相同的应用程序代码。

    您可以使用各种外部配置源,包括 Java properties文件YAML文件环境变量命令行参数

    Ⅱ. 配置文件查找位置

    Spring Boot将自动查找并加载应用程序、特性和应用。应用程序启动时,来自以下位置的yaml文件:

    1. classpath 根路径。
    2. classpath 根路径下config目录。
    3. jar包当前目录。
    4. jar包当前目录的config目录。
    5. /config子目录的直接子目录(Linux系统中)。

    列表按优先级排序(较低项的值优先于较早项)。加载文件中的文档作为PropertySources添加到Spring环境中。

    Ⅲ. 配置文件加载顺序

    1. 当前jar包内部的application.propertiesapplication.yml
    2. 当前jar包内部的application-{profile}.propertiesapplication-{profile}.yml
    3. 引用的外部jar包的application.propertiesapplication.yml
    4. 引用的外部jar包的application-{profile}.propertiesapplication-{profile}.yml

    指定环境优先,外部优先,后面的可以覆盖前面的同名配置项。

    3. 自定义starter

    Ⅰ. starter启动原理

    • starter的pom.xml引入autoconfigure依赖包
    starter
    autoconfigure
    spring-boot-starter
    • autoconfigure包中配置使用META-INF/spring.factoriesEnableAutoConfiguration的值,使得项目启动加载指定的自动配置类

    • 编写自动配置类 xxxAutoConfiguration => xxxxProperties

      @Configuration

      @Conditional

      @EnableConfigurationProperties

      @Bean

      ➢ …

    • 引入starter — xxxAutoConfiguration — 容器中放入组件 ---- 绑定xxxProperties ---- 配置项

    Ⅱ. 自定义starter

    • 目标:创建HelloService的自定义starter。

    • 创建两个工程,分别命名为hello-spring-boot-starter(普通Maven工程),hello-spring-boot-starter-autoconfigure(需用用到Spring Initializr创建的Maven工程)。

    • hello-spring-boot-starter无需编写什么代码,只需让该工程引入hello-spring-boot-starter-autoconfigure依赖:

      
      <project xmlns="http://maven.apache.org/POM/4.0.0"
               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
          <modelVersion>4.0.0modelVersion>
      
          <groupId>com.atguigugroupId>
          <artifactId>hello-spring-boot-starterartifactId>
          <version>1.0.0-SNAPSHOTversion>
      
          <dependencies>
              <dependency>
                  <groupId>com.atguigugroupId>
                  <artifactId>hello-spring-boot-starter-autoconfigureartifactId>
                  <version>1.0.0-SNAPSHOTversion>
              dependency>
          dependencies>
      
      project>
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
    • hello-spring-boot-starter-autoconfigure的pom.xml如下:

      
      <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
      	<modelVersion>4.0.0modelVersion>
      	<parent>
      		<groupId>org.springframework.bootgroupId>
      		<artifactId>spring-boot-starter-parentartifactId>
      		<version>2.4.2version>
      		<relativePath/> 
      	parent>
      	<groupId>com.atguigugroupId>
      	<artifactId>hello-spring-boot-starter-autoconfigureartifactId>
      	<version>1.0.0-SNAPSHOTversion>
      	<name>hello-spring-boot-starter-autoconfigurename>
      	<description>Demo project for Spring Bootdescription>
      	<properties>
      		<java.version>1.8java.version>
      	properties>
      	<dependencies>
      		<dependency>
      			<groupId>org.springframework.bootgroupId>
      			<artifactId>spring-boot-starterartifactId>
      		dependency>
      	dependencies>
      project>
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
    • 创建4个文件:

      com/atguigu/hello/auto/HelloServiceAutoConfiguration

      import com.atguigu.hello.bean.HelloProperties;
      import com.atguigu.hello.service.HelloService;
      import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
      import org.springframework.boot.context.properties.EnableConfigurationProperties;
      import org.springframework.context.annotation.Bean;
      import org.springframework.context.annotation.Configuration;
      
      @Configuration
      @EnableConfigurationProperties(HelloProperties.class) // 默认HelloProperties放在容器中
      public class HelloServiceAutoConfiguration {
      
          @ConditionalOnMissingBean(HelloService.class)
          @Bean
          public HelloService helloService(){
              return new HelloService();
          }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17

      com/atguigu/hello/bean/HelloProperties

      import org.springframework.boot.context.properties.ConfigurationProperties;
      
      @ConfigurationProperties("hello")
      public class HelloProperties {
          private String prefix;
          private String suffix;
      
          public String getPrefix() {
              return prefix;
          }
      
          public void setPrefix(String prefix) {
              this.prefix = prefix;
          }
      
          public String getSuffix() {
              return suffix;
          }
      
          public void setSuffix(String suffix) {
              this.suffix = suffix;
          }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23

      com/atguigu/hello/service/HelloService

      import com.atguigu.hello.bean.HelloProperties;
      import org.springframework.beans.factory.annotation.Autowired;
      
      /**
       * 默认不要放在容器中
       */
      public class HelloService {
      
          @Autowired
          private HelloProperties helloProperties;
      
          public String sayHello(String userName) {
              return helloProperties.getPrefix() + ": " + userName + " > " + helloProperties.getSuffix();
          }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15

      src/main/resources/META-INF/spring.factories

      # Auto Configure
      org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
      com.atguigu.hello.auto.HelloServiceAutoConfiguration
      
      • 1
      • 2
      • 3
    • 用maven插件,将两个工程install到本地。

    • 接下来,测试使用自定义starter,用Spring Initializr创建名为hello-spring-boot-starter-test工程,引入hello-spring-boot-starter依赖,其pom.xml如下:

      
      <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
          <modelVersion>4.0.0modelVersion>
          <parent>
              <groupId>org.springframework.bootgroupId>
              <artifactId>spring-boot-starter-parentartifactId>
              <version>2.4.2version>
              <relativePath/> 
          parent>
          <groupId>com.atguigugroupId>
          <artifactId>hello-spring-boot-starter-testartifactId>
          <version>1.0.0-SNAPSHOTversion>
          <name>hello-spring-boot-starter-testname>
          <description>Demo project for Spring Bootdescription>
          <properties>
              <java.version>1.8java.version>
          properties>
          <dependencies>
              <dependency>
                  <groupId>org.springframework.bootgroupId>
                  <artifactId>spring-boot-starterartifactId>
              dependency>
      
              <dependency>
                  <groupId>org.springframework.bootgroupId>
                  <artifactId>spring-boot-starter-testartifactId>
                  <scope>testscope>
              dependency>
      
              
              <dependency>
                  <groupId>com.atguigugroupId>
                  <artifactId>hello-spring-boot-starterartifactId>
                  <version>1.0.0-SNAPSHOTversion>
              dependency>
      
          dependencies>
      
          <build>
              <plugins>
                  <plugin>
                      <groupId>org.springframework.bootgroupId>
                      <artifactId>spring-boot-maven-pluginartifactId>
                  plugin>
              plugins>
          build>
      
      project>
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
      • 36
      • 37
      • 38
      • 39
      • 40
      • 41
      • 42
      • 43
      • 44
      • 45
      • 46
      • 47
      • 48
      • 49
    • 添加配置文件application.properties

      hello.prefix=ATGUIGU
      hello.suffix=6666
      
      • 1
      • 2
    • 编写新项目的Controller

      import com.atguigu.hello.service.HelloService; // 来自自定义starter
      import org.springframework.beans.factory.annotation.Autowired;
      import org.springframework.web.bind.annotation.GetMapping;
      import org.springframework.web.bind.annotation.RestController;
      
      @RestController
      public class HelloController {
      
          @Autowired
          HelloService helloService;
      
          @GetMapping("/hello")
          public String sayHello() {
              String s = helloService.sayHello("张三");
              return s;
          }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17

      image-20220727195516892

  • 相关阅读:
    ITSS认证系统运维范围定义
    openjudge 1.5.24 正常血压
    PLC中ST编程的无符号数逻辑运算
    【m98】视频帧的 jitterbuffer 1:
    Android 10 如何在SurfaceFlinger中解决开机动画显示不全问题
    leetCode 11. 盛最多水的容器 + 双指针
    地理知识:墨卡托坐标系
    在Windows上安装Docker与k8s,完美亲测!
    Gopher进阶神器:拥抱刻意练习,从新手到大师。
    spring mvc上传文件MultipartHttpServletRequest值为空
  • 原文地址:https://blog.csdn.net/weixin_53407527/article/details/126042080