• 「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

  • 相关阅读:
    宏观视角下的浏览器
    【算法|动态规划No.27】leetcode516. 最长回文子序列
    NXP i.MX 8M Mini工业核心板B2B版本,4核ARM Cortex-A53@1.6GHz设计
    在vscode中配置anaconda环境的操作感悟
    五款外文写作阅读工具推荐,赶紧收藏起来!
    网络安全(黑客)自学
    分割等和子集【动态规划】
    【老生谈算法】matlab实现图像滤波处理算法源码——图像滤波处理算法
    java基于springboot+vue在线考试系统39n99
    Java之线程
  • 原文地址:https://blog.csdn.net/weixin_53407527/article/details/126042080