「SpringBoot」08 高级特性

SpringBoot——高级特性

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

1. Profile功能

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

Ⅰ. application-profile功能

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

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

    application-test.yaml

    person:
      name: test-张三
    server:
      port: 7000
    

    application-prod.yaml

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

    ➢ 配置文件激活

    application.properties

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

    ➢ 命令行激活: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;
}

Controller

@RestController
public class HelloController {
    
    @Autowired
    private Person person;
    
    @GetMapping("/")
    public String hello() {
        return person.getClass().toString();
    }
}

@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();
    }
}

Ⅲ. Profile分组

spring.profiles.active=production

spring.profiles.group.production[0]=proddb
spring.profiles.group.production[1]=prodmq

# 使用:--spring.profiles.active=production 激活

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;

    // ...

}

Ⅰ. 外部配置源

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依赖:

    <?xml version="1.0" encoding="UTF-8"?>
    <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.0</modelVersion>
    
        <groupId>com.atguigu</groupId>
        <artifactId>hello-spring-boot-starter</artifactId>
        <version>1.0.0-SNAPSHOT</version>
    
        <dependencies>
            <dependency>
                <groupId>com.atguigu</groupId>
                <artifactId>hello-spring-boot-starter-autoconfigure</artifactId>
                <version>1.0.0-SNAPSHOT</version>
            </dependency>
        </dependencies>
    
    </project>
    
  • hello-spring-boot-starter-autoconfigure的pom.xml如下:

    <?xml version="1.0" encoding="UTF-8"?>
    <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.0</modelVersion>
    	<parent>
    		<groupId>org.springframework.boot</groupId>
    		<artifactId>spring-boot-starter-parent</artifactId>
    		<version>2.4.2</version>
    		<relativePath/> <!-- lookup parent from repository -->
    	</parent>
    	<groupId>com.atguigu</groupId>
    	<artifactId>hello-spring-boot-starter-autoconfigure</artifactId>
    	<version>1.0.0-SNAPSHOT</version>
    	<name>hello-spring-boot-starter-autoconfigure</name>
    	<description>Demo project for Spring Boot</description>
    	<properties>
    		<java.version>1.8</java.version>
    	</properties>
    	<dependencies>
    		<dependency>
    			<groupId>org.springframework.boot</groupId>
    			<artifactId>spring-boot-starter</artifactId>
    		</dependency>
    	</dependencies>
    </project>
    
  • 创建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();
        }
    }
    

    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;
        }
    }
    

    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();
        }
    }
    

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

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

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

    <?xml version="1.0" encoding="UTF-8"?>
    <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.0</modelVersion>
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.4.2</version>
            <relativePath/> <!-- lookup parent from repository -->
        </parent>
        <groupId>com.atguigu</groupId>
        <artifactId>hello-spring-boot-starter-test</artifactId>
        <version>1.0.0-SNAPSHOT</version>
        <name>hello-spring-boot-starter-test</name>
        <description>Demo project for Spring Boot</description>
        <properties>
            <java.version>1.8</java.version>
        </properties>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
    
            <!-- 引入hello-spring-boot-starter依赖 -->
            <dependency>
                <groupId>com.atguigu</groupId>
                <artifactId>hello-spring-boot-starter</artifactId>
                <version>1.0.0-SNAPSHOT</version>
            </dependency>
    
        </dependencies>
    
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
            </plugins>
        </build>
    
    </project>
    
  • 添加配置文件application.properties

    hello.prefix=ATGUIGU
    hello.suffix=6666
    
  • 编写新项目的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;
        }
    }
    

    image-20220727195516892

  • 5
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小成同学_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值