Spring Boot | Spring Boot的“核心配置“与“注解“

发布于:2024-03-31 ⋅ 阅读:(68) ⋅ 点赞:(0)

目录:

Spring Boot的核心配置与注解 :

在这里插入图片描述

作者简介 :一只大皮卡丘,计算机专业学生,正在努力学习、努力敲代码中! 让我们一起继续努力学习!

该文章参考学习教材为:
《Spring Boot企业级开发教程》 黑马程序员 / 编著
文章以课本知识点 + 代码为主线,结合自己看书学习过程中的理解和感悟 ,最终成就了该文章

文章用于本人学习使用 , 同时希望能帮助大家。
欢迎大家点赞👍 收藏⭐ 关注💖哦!!!

(侵权可联系我,进行删除,如果雷同,纯属巧合)


1. 全局配置文件 ( application.properties / application.yaml:创建项目时候自动生成,其会被“自动导入”到“程序”中 )

  • 全局配置文件 ( applicationContext.properties )能够对一些 默认配置值进行修改Spring Boot 使用一个 ① application.properties 或者 ② application.yaml文件作为 全局配置文件该文件存放src/main/resource目录 或者 类路径的 /config,一般会选择 resource目录

application.properties配置文件

  • 使用 Spring Initializr方式构建Spring Boot项目时,会在 src/main/resources目录自动生成一个空 application.properties文件Spring Boot项目启动时自动加载application.properties文件

  • 我们可以在application.properties 文件中定义 Spring Boot 项目相关属性,当然,这些相关属性可以是 系统属性环境变量命令参数等信息,也可以是 自定义配置文件名称位置示例代码如下:

    spring.application.name=chapter_02
    server.address=80
    server.port=8443
    spring.datasource.driver-class-name=com.mysql.jdbc.Driver
    spring.config.additional-location=
    spring.config.location=
    spring.config.name=application
    
  • 关于applicationContext.properties案例 ( 例子如 ) :

    Pet.java :

    package com.myh.chapter_03.domain;
    
    public class Pet {
    
        private String type;
        private String name;
    
        public String getType() {
            return type;
        }
    
        public void setType(String type) {
            this.type = type;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        @Override
        public String toString() {
            return "Pet{" +
                    "type='" + type + '\'' +
                    ", name='" + name + '\'' +
                    '}';
        }
    
    }
    

    Person.java

    package com.myh.chapter_03.domain;
    
    import org.springframework.boot.context.properties.ConfigurationProperties;
    import org.springframework.stereotype.Component;
    
    import java.util.Arrays;
    import java.util.List;
    import java.util.Map;
    
    @Component //用于将Person类加入到IOC容器中 (只有这样Person对象才能被 @ConfigurationProperties()注解赋值 )
    
    @ConfigurationProperties(prefix = "person")//将配置文件(application.properties)中以person开头的数据通过“set方法”注入到该类中"属性"
    public class Person {
    
        /**
         * 通过 @ConfigurationProperties(prefix = "person") 注解来将 application.properties中的"数据"注入到
         * 下面的“属性”中
         */
        private int id;
        private String name;
        private List hobby;
        private String[] family;
        private Map map;
        private Pet pet;
    
        public int getId() {
            return id;
        }
    
        public void setId(int id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public List getHobby() {
            return hobby;
        }
    
        public void setHobby(List hobby) {
            this.hobby = hobby;
        }
    
        public String[] getFamily() {
            return family;
        }
    
        public void setFamily(String[] family) {
            this.family = family;
        }
    
        public Map getMap() {
            return map;
        }
    
        public void setMap(Map map) {
            this.map = map;
        }
    
        public Pet getPet() {
            return pet;
        }
    
        public void setPet(Pet pet) {
            this.pet = pet;
        }
    
        @Override
        public String toString() {
            return "Person{" +
                    "id=" + id +
                    ", name='" + name + '\'' +
                    ", hobby=" + hobby +
                    ", family=" + Arrays.toString(family) +
                    ", map=" + map +
                    ", pet=" + pet +
                    '}';
        }
    }
    

    @ConfigurationProperties(prefix =“person”)注解作用 是将配置文件person开头属性值通过setter方法注入实体类对应属性 中。@Component注解 的作用是当前注入属性值的 Person类对象作为 Bean 组件放到 Spring 容器中,只有 这样它才能被 @ConfigurationProperties注解赋值

    上述自定义 Person类中,添加了一个 @Component注解,将该自定义类作为 Spring容器的组件 ( 简而言之,就是 该类给IOC容器管理 ),其根本目的是让 Spring Boot 可以自动扫描到该组件,然后进行其他功能实现。


    application.properties

    #对实体类对象Person进行属性配置
    person.id = 1
    person.name = tom
    person.hobby = play,read,sleep
    person.family = father,mother
    person.map.k1 = v1
    person.map.k2 = v2
    person.pet.type = dog
    person.pet.name = kity
    

    Spring Boot默认全局配置文件 : application.properties 中的数值将会通过 @ConfigurationProperties( ) 注解 注入到对应实体类 中。


    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.1.3.RELEASE</version>
            <relativePath/> <!-- lookup parent from repository -->
        </parent>
    
        <groupId>com.myh</groupId>
        <artifactId>chapter_03</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <name>chapter_03</name>
        <description>Demo project for Spring Boot</description>
    
        <properties>
            <java.version>1.8</java.version>
        </properties>
    
        <dependencies>
            <!--    web应用场景依赖启动器    -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
    
            <!--    单元测试依赖启动器    -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
    
            <dependency>
                <groupId>org.junit.jupiter</groupId>
                <artifactId>junit-jupiter</artifactId>
                <version>RELEASE</version>
                <scope>test</scope>
            </dependency>
    
            <!--   “热部署”依赖启动器   -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-devtools</artifactId>
            </dependency>
    
            <!--   是生成配置元数据,以提供更好的配置文件支持和开发体验。它能够帮助开发人员更方便地使用配置文件,并提高开发效率   -->
            <!--
              在编写application.properties配置文件时,由于要配置的Person 对象属性是我们自定义的,SpringBoot 无法自动识别,所以不会有任何书写提示。在实际开发中,为了出现代码提示的效果来方便配置,在使用@ConfigurationProperties注解进行配置文件属性值注入时,可以在pom.xmI文件中添加一个Spring Boot 提供的配置处理器依赖
                 -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-configuration-processor</artifactId>
            </dependency>
        </dependencies>
    
        <!--    Maven打包工具插件   -->
    <!--    <build>-->
    <!--        <plugins>-->
    <!--            <plugin>-->
    <!--                <groupId>org.springframework.boot</groupId>-->
    <!--                <artifactId>spring-boot-maven-plugin</artifactId>-->
    <!--            </plugin>-->
    <!--        </plugins>-->
    <!--    </build>-->
    
    </project>
    

    Chapter03ApplicationTests.java ( 单元测试类 ):

    package com.myh.chapter_03;
    
    import com.myh.chapter_03.domain.Person;
    import org.junit.jupiter.api.Test;
    import org.junit.runner.RunWith;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.context.SpringBootTest;
    import org.springframework.test.context.junit4.SpringRunner;
    
    @RunWith(SpringRunner.class) //测试运行器,并加载SpringBoot测试注解
    @SpringBootTest //标记该类为“单元测试类”,并加载项目的上下文环境ApplicationContext
    class Chapter03ApplicationTests {
    
        @Autowired
        private Person person;
    
        @Test
        void contextLoads() {
            System.out.println(person);
        }
    }
    

    运行 contextLoads( )方法控制台输出结果如下图所示 :
    在这里插入图片描述
    方法执行结果.jpg)信息成功打印,说明了 application.properties文件 属性配置正确,并通过 相关注解自动完成属性注入

application.yaml 配置文件 (推荐使用)

  • YAML文件格式Spring Boot 支持 的一种 JSON 超集文件格式,相较于传统Properties配置文件YAML文件数据核心,是一种更为 直观容易被计算机识别数据序列化格式
  • application.yaml 配置文件的 工作原理application.properties一样的,只不过YAML格式配置文件看起来 更简洁一些
  • application.yaml 文件用“ key: + 空格 + value”格式配置属性,使用缩进控制层级关系。这里我们 针对不同数据类型属性值,介绍一下YAML文件配置属性写法,具体如下所示 。
当value值为 “普通数据类型” (如 : 数字、字符串、布尔等)
  • (1) value 值为 普通数据类型( 如数字字符串布尔等)
    YAML 配置文件中配置的 属性值普通数据类型 时,可以 直接配置对应属性值,同时对 字符串类型属性值不需要额外添加引号示例代码如下

    #当属性值为普通数据类型(如:数字、字符串、布尔等),属性值不需要”额外添加引号“
    #8081 和 /hello因为是"普通数据类型",所以都没添加额外的引号
    #port和path属于“同一级别”
    Server:
      port: 8081
      path: /hello
    
当value值为 “数组” 或 “单列集合”
  • (2) value 值为 数组单列集合
    YAML 配置文件中配置的 属性值数组单列集合类型 时,主要有 两种书写方式①缩进式写法②行内式写法

    ①缩进式写法 :

    #缩进式写法
    person1:
      hobby:
        - play
        - read
        - sleep
    
    person2:
      hobby:
        play,
        read,
        sleep  
    

    ②行内式写法 :

    #行内式写法
    person4:
      hobby: [play,read,sleep]
    
    #使用行内式设置属性值时, []是可以省略的,程序会自动匹配校队"属性的值"
    person5:
      hobby: play,read,sleep
    
当value值为 “Map集合” 或 “对象类型”
  • (3) value 值为 Map 集合对象类型 时,主要同样 有两种书写方式①缩进式写法②行内式写法

    ①缩进式写法 :

    #value值为Map或对象时的写法
    #Map类型
    #缩进式写法
    person6:
      map:
        k1: v1
        k2: v2
    

    ②行内式写法 :

    #Map类型
    #行内式写法,此处用的符号是: 大括号{}
    person7:
      map: {k1: v1,k2: k3}
    

    ps :

    此处用的 符号 是: 大括号{ }

application.yaml 配置文件的“应用案例”
  • application.yaml :

    #对实体类对象Person进行属性设置, 一样是通过 @ConfigurationProperties()注解来将下面的"数据值"注入到"类"的"属性"中的
    person2:
      id: 1
      name: 张三
      hobby: [play,read,sleep]
      family: [father,mother]
      map: {k1: v1,k2: v2}
      pet: {type: dog,name: kitty}
    

    Person.java :

    package com.myh.chapter_03.domain;
    
    import org.springframework.boot.context.properties.ConfigurationProperties;
    import org.springframework.stereotype.Component;
    
    import java.util.Arrays;
    import java.util.List;
    import java.util.Map;
    
    @Component //用于将Person类加入到IOC容器中 (只有这样Person对象才能被 @ConfigurationProperties()注解赋值 )
    
    @ConfigurationProperties(prefix = "person2")//将配置文件( application.yaml )中以person2开头的数据通过“set方法”注入到该类中"属性"
    public class Person {
    
        /**
         * 通过 @ConfigurationProperties(prefix = "person") 注解来将 application.properties中的"数据"注入到
         * 下面的“属性”中
         */
        private int id;
        private String name;
        private List hobby;
        private String[] family;
        private Map map;
        private Pet pet;
    
        public int getId() {
            return id;
        }
    
        public void setId(int id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public List getHobby() {
            return hobby;
        }
    
        public void setHobby(List hobby) {
            this.hobby = hobby;
        }
    
        public String[] getFamily() {
            return family;
        }
    
        public void setFamily(String[] family) {
            this.family = family;
        }
    
        public Map getMap() {
            return map;
        }
    
        public void setMap(Map map) {
            this.map = map;
        }
    
        public Pet getPet() {
            return pet;
        }
    
        public void setPet(Pet pet) {
            this.pet = pet;
        }
    
        @Override
        public String toString() {
            return "Person{" +
                    "id=" + id +
                    ", name='" + name + '\'' +
                    ", hobby=" + hobby +
                    ", family=" + Arrays.toString(family) +
                    ", map=" + map +
                    ", pet=" + pet +
                    '}';
        }
    }
    

    Chapter03ApplicationTests.java ( 单元测试类 ):

    package com.myh.chapter_03;
    
    import com.myh.chapter_03.domain.Person;
    import org.junit.jupiter.api.Test;
    import org.junit.runner.RunWith;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.context.SpringBootTest;
    import org.springframework.test.context.junit4.SpringRunner;
    
    @RunWith(SpringRunner.class) //测试运行器,并加载SpringBoot测试注解
    @SpringBootTest //标记该类为“单元测试类”,并加载项目的上下文环境ApplicationContext
    class Chapter03ApplicationTests {
    
        @Autowired
        private Person person;
    
        @Test
        void contextLoads() {
            System.out.println(person);
        }
    }
    

    运行 contextLoads( )方法控制台输出结果如下图所示 :
    在这里插入图片描述
    信息成功打印,说明了 application.yaml文件 属性配置正确,并通过 相关注解自动完成属性注入

    通过对比可以发现YAML配置文件的格式更加简洁、方便推荐使用YAML格式文件

2. “配置文件属性值” 的 “注入”

  • 使用Spring Boo 全局配置文件 ( application.properties / application.yaml )配置 属性 时, 如果配置的属性Spring Boot 默认提供的属性 ,例如服务器端口server.port,那么Spring Boot内部会自动扫描并读取属性值 ( 因为那是 默认提供的属性 )。 如果配置的属性是 用户自定义属性,例如 :自定义Person 实体类属性,则必须在程序中注入这些配置属性 ( 通过 @ConfigurationProperties( )注解进行“属性值”的注入 )方可生效。

  • Spring Boot 支持 多种注入配置文件属性方式 :

    使用 注解@ConfigurationProperties ( )注解“注入属性” 使用 @Value( )注解 “注入属性”

使用@ConfigurationProperties( )注解将“配置文件”中的“属性值”注入到“属性”中 (注入“个别属性值”)

  • Spring Boot提供的 @ConfigurationProperties注解 用来快速、方便地 配置文件中自定义
    属性值批量注入 某个Bean 对象多个对应属性
    中。假设现在有一个配置文件,使用 @ConfigurationProperties 注入配置文件的属性示例代码如下 :

    @Component //将该类交给IOC容器管理,变成一个bean
    //该注解的作用: 将配置文件中自定义的"属性值"注入到某个bean对象中的"对应属性"中
    @ConfigurationProperties(prefix = "person")//将配置文件( application.properties/application.yaml )中以后person开头的数据通过“set方法”注入到该类中"属性"
    public class Person {
        private int id;
        
        //属性的set方法
        public void setId(int id) {
            this.id = id;
        }
    }
    

    上述代码使用 @Component@ConfigurationProperties(prefix =“person”)配置文件中每个属性映射person类属性中
    需要注意 的是,使用 @ConfigurationProperties 注解 批量注入属性值 时,要保证配置文件中的 属性 与对应实体类的 属性名一致否则无法 正确 获取并注入属性值

使用@Value( )注解将“配置文件”中的“属性值”注入到“属性”中 (注入“个别属性值”)

  • @Value注解Spring框架提 供的,用来 读取配置文件中的属性值 并逐个 注入Bean对象对应属性Spring Boot 框架对Spring 框架中的 @Value注解进行了 默认继承,所以在Spring Boot 框架中还可以使用该注解 读取注入配置文件属性值

    @Component //将该类交给IOC容器管理,变成一个bean
    public class Person {
        
        @Value("${person.id}") //将配置文件中的“属性值”注入到该类的属性中
        private int id;
    }
    

    上述代码中,@Component注解@Value注解用于 注入Personid属性。其中,@Value 不仅支持注入Person的 id 属性,而且 还可以直接id属性赋值,这是 @ConfigurationProperties( )注解 不支持 的。

  • 例子如

    Student.java

    package com.myh.chapter_03.domain;
    
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.stereotype.Component;
    
    import java.util.Arrays;
    import java.util.List;
    import java.util.Map;
    
    @Component //将该类添加到IOC容器中,作为一个bean(被IOC容器管理)
    public class Student {
    
        //用该注解将配置文件中的"属性值"注入到该类的“属性”中
        @Value("${person.id}")
        private int id;
        @Value("${person.name}")
        private String name;
        private List hobby;
        private String[] family;
        private Map map;
        private Pet pet;
    
        @Override
        public String toString() {
            return "Student{" +
                    "id=" + id +
                    ", name='" + name + '\'' +
                    ", hobby=" + hobby +
                    ", family=" + Arrays.toString(family) +
                    ", map=" + map +
                    ", pet=" + pet +
                    '}';
        }
    }
    

    pom.xml

    #对实体类对象Person进行属性设置, 一样是通过 @ConfigurationProperties()注解来将下面的"数据值"注入到"类"的"属性"中的
    person:
      id: 1
      name: tom
      hobby: [play,read,sleep]
      family: [father,mother]
      map: {k1: v1,k2: v2}
      pet: {type: dog,name: kitty}
    

    Chapter03ApplicationTests.java (测试类):

    package com.myh.chapter_03;
    
    import com.myh.chapter_03.domain.Person;
    import com.myh.chapter_03.domain.Student;
    import org.junit.jupiter.api.Test;
    import org.junit.runner.RunWith;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.context.SpringBootTest;
    import org.springframework.test.context.junit4.SpringRunner;
    
    @RunWith(SpringRunner.class) //测试运行器,并加载SpringBoot测试注解
    @SpringBootTest //标记该类为“单元测试类”,并加载项目的上下文环境ApplicationContext
    class Chapter03ApplicationTests {
    
        @Autowired
        private Student student;
        
        @Test
        public void studentTest() {
            System.out.println(student);
        }
    }
    

    运行 studentTest( )方法控制台输出结果如下图所示 :
    在这里插入图片描述

    注意点

    使用 @Value( )注解 注入的 属性类型 只能是“ 基本数据类型”。

两种注解“对比分析” :

  • @ConfigurationProperties( )注解@Value( )注解对比 如下表所示

    对比 @ConfigurationProperties( )注解 @Value( )注解
    底层框架 SpringBoot Spring
    功能 批量注入配置文件中的属性 单个注入
    setter 方法 需要 不需要
    复杂类型属性注入 支持 支持
    松散绑定 支持 不支持
    JSR303 数据校验 支持 不支持
    SpEL表达式 不支持 支持
底层框架

@ConfigurationProperties注解是 Spring Boot框架自带 的;而 @Value 注解Spring 框架支持的,
只不过Spring Boot框架对Spring 进行了 默认支持,所以也可以使用@Value 注解的相关功能。

功能

@ConfigurationProperties能够将配置文件中的属性 批量注入 Bean对象,而@Value 只能 一个一个单独注入

属性 setter 方法
  • 在使用 @ConfigurationProperties注解进行配置文件 属性值读取注入 时,还必须为 每一个属性 设置 setter方法,通过对应的注解才能够将配置文件中属性一一匹配并注入对应的 Bean 属性上。如果配置文件中没有配置属性值,则会自动将对应的 Bean 属性设置为空。
    @ConfigurationProperties注解必须为每一个属性设setter方法,这样才能完成属性值的注入
  • @Value 完全不需要为属性设置setter方法,该注解会先通过表达式读取配置文件中指定的属性值,然后自动注入下方的Bean属性上。如果读取的配置文件属性为空,进行属性注入时程序会自动报错
复杂类型属性注入

@ConfigurationProperties( )注解 和 @Value注解 支持 任意数据类型属性注入,包括基本数据类型复杂数据类型

松散绑定
  • @ConfigurationProperties注解进行配置文件属性注入时,支持松散绑定语法。例如Person类有一个字符串类型的属性firstName,那么在配置文件中进行属性配置时可以使用如下配置方式示例代码如下 :

    person.firstName = james //标准写法,对应Person类属性名
    person.first-name = james //使用横线“-”分隔多个单词
    person.first_name = james //使用下划线"_"分隔多个单词
    person.FIRST_NAME = james //使用大小写格式,推荐常量属性配置
    
    

    如果要 注入上述松散绑定语法属性,那么使用 @Value 注入无效的,只能使用@ConfigurationProperties

JSR303 数据校验
  • @ConfigurationProperties注解进行配置文件属性值注入时,支持JSR303数据校验 ,其主要作用是 校验配置文件注入对应Bean属性 的值是否符合相关值的规则,示例代码如下 :

    @Component //加入到IOC容器中
    @ConfigurationProperties(prefix = "person")
    @Validated //引入Spring框架支持的"数据校验规则"
    public class Example {
    
        @Email //对属性进行规则匹配
        private String email;
    
        public void setEmail(String email) {
            this.email = email;
        }
    }
    
    

    上述代码中,使用 @ConfigurationProperties注解注入配置文件属性值时,在实体类Example上引入 @Validated 注解行数据校验,在属性email 上引入@Email 注解进行邮件规则校验。如果注入的配置文件属性值不符合相关校验规则,程序会自动报错。@Value 注解不支持 JSR303数据校验功能

SpEL表达式 ( 使用“SpEL表达式”为属性“直接注入值” )
  • @Value 注解 注入配置文件属性时,支持 SpEL表达式语法,即“#{xx}”。例如 Person 类有一个整数类型的属性id,直接使用 SpEL 表达式语法进行属性注入使用SpEL表达式直接为属性注入值
    示例代码如下

     //用SpEL来定义一个值, #{5*2} 是一个简单的数学表达式,它计算 5乘以 2的结果,将给结果注入到id属性中 
    @Value("#{5*2}") 
    private int id;
    

    上述代码不使用配置文件 的情况下,直接使用 @Value注解 支持的 SpEL表达式注入Bean ( 通过该 注解支持的SpEL表达式来“直接”为“属性注入值 )。而 @ConfigurationProperties注解 不支持此功能

如何选择使用这“两种注解”?

  • 如果只是针对某一个业务需求,要引入配置文件中个别属性值,推荐使用 @Value( )注解
    ( 如果只要 注入一两个属性值,用 @Value( )注解
  • 如果针对某个JavaBean类,需要 批量注入属性值,则推荐使用@ConfigurationProperties( )注解
    注解。
    (如果要 注入多个属性值推荐使用 @ConfigurationProperties( )注解

3. Spring Boot “自定义配置” (“自定义配置文件”时,需要手动加载该配置文件)

  • Spring Boot 免除了项目中大部分的手动配置,对于 一些特定情况,我们可以通过修改全局配置文件适应具体生产环境,可以说,几乎 所有的配置都可以 写在全局配置文件SpringBoot自动加载全局配置文件 从而免除我们手动加载烦恼
  • 但是,如果我们自定义配置文件Spring Boot无法识别 这些 配置文件 的,此时就需要我们 手动加载

使用@PropertySource( )注解 “加载Properties配置文件”

  • 如果 要加载自定义配置文件,可以使用 @PropertySource( )注解 和 @ Configuration( )注解 实现。
    @PropertySource注解可以指定 自定义配置文件位置名称
    @Configuration注解可以 将实体类指定自定义配置类

    系统默认的的配置文件为 : spring.properties ,系统会 自动加载该配置文件 的,但如果是自己创建一个新的配置文件系统不会进行加载,要手动配置系统才能进行加载。)

  • 如果需要自定义配置文件中的属性值注入实体类属性,可以使用 @ConfigurationProperties( ) 注解 或 @Value( ) 注解 注入属性值

  • 例子如 :

    打开项目的 resources目录,在项目的类路径下新建一个 test.properties :

    #该配置文件为“自定义的配置文件”,要进行配置后,系统才会加载该“配置文件”
    #对实体类对象Myproperties进行属性配置
    test.id = 1
    test.name = test
    

    MyProperties.java

    package com.myh.chapter_03.domain;
    import org.springframework.boot.context.properties.ConfigurationProperties;
    import org.springframework.boot.context.properties.EnableConfigurationProperties;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.PropertySource;
    
    /**
     * ①"@Configuration"注解用于定义"配置类",注解中包含了一些方法,这些方法会产生Bean,并交由Spring容器管理。
     * ( 该注解和 @Component注解功能类似 : 都是将给该类加入到IOC容器中,被IOC容器管理 )
     *
     * ②@Configuration注解标记类为“配置类”,这里等同于“@Component注解”
     */
    @Configuration //标记该类为"配置类",将给类交给IOC容器管理
    @PropertySource("classpath:test.properties") //指定"自定义的配置文件"的位置
    /**
       @EnableConfigurationProperties()注解是配合 @ConfigurationProperties()注解一起使用的。如果自定义配置类使用了
       @Component()注解而非 @Configuration()注解时,那么@EnableConfigurationProperties()注解可以省略
     */
    @EnableConfigurationProperties(MyProperties.class) //开启“该配置类”的“属性注入功能”
    @ConfigurationProperties("test") //指定将“自定义的配置文件”中以test开头的属性值注入到类中属性
    public class MyProperties { //自定义的"配置类",用于借助相关注解来引入“自定义配置文件”并注入“属性值”
    
        private int id;
        private String name;
    
        public int getId() {
            return id;
        }
    
        public void setId(int id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        @Override
        public String toString() {
            return "MyProperties{" +
                    "id=" + id +
                    ", name='" + name + '\'' +
                    '}';
        }
    }
    

    上述文件中,MyProperties 是一个 自定义配置类,用于借助相关注解引入 自定义配置文件注入自定义属性值。上面的类中用到的注解介绍具体如下

    注解 描述
    @Configuration( )注解 @Configuration注解用于表示当前类是一个自定义配置类,该类会作为Bean 组件添加到Spring 容器,这里等 同于@Component 注解
    @PropertySource( )注解 @PropertySource(“classpath:test.properties”)注解指定了自定义配置文件位置名称
    此示例表示自定义配置文件classpath类路径下的test.properties 文件
    @ConfigurationProperties( )注解 @ConfigurationProperties(prefix = “test”) 注解将上述 自定义配置文件 test.properties 中以test 开头属性值注入该配置类属性中。
    @EnableConfigurationProperties
    (MyProperties.class)
    该注解表示开启对应配置类MyProperties属性注入功能,该注解是配合 @ConfigurationProperties 使用的。如果自定义配置类使用了 @Component 注解非@Configuration注解,那么 @EnableConfigurationProperties注解以省略

    Chapter03ApplicationTests3.java : (测试类) :

    package com.myh.chapter_03;
    
    import com.myh.chapter_03.domain.MyProperties;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.context.SpringBootTest;
    import org.springframework.test.context.junit4.SpringRunner;
    
    @RunWith(SpringRunner.class)
    @SpringBootTest //标记该类为“单元测试类”,并加载项目的上下文环境ApplicationContext
    public class Chapter03ApplicationTests3 {
    
    
   @Autowired
	    private MyProperties myProperties;
   @Test
    public void myPropertiesTest() {
        System.out.println(myProperties);
    }
}

执行 myPropertiesTest( )方法查看控制台输出效果
在这里插入图片描述

使用@lmportResource( )注解 “加载XML配置文件”

  • 传统的 Spring 项目 配置主要 基于XML文件Spring Boot框架Spring4.x基础上进行了改进默认不再使用 XML文件配置项目,且XML配置文件不会加载到Spring容器中。如果希望将外部的XML文件加载到程序中,可以使用 @lmportResource( )注解 加载配置文件

  • @lmportResource( )注解 标注在一个 配置类 上,通常放置在应用启动类上,使用时需要 指定 XML 配置文件路径和名称

  • 例子如 :

    打开项目的 resources目录,新建一个 beans.xml :

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
    	http://www.springframework.org/schema/beans/spring-beans.xsd">
    
        <!--  通过bean标签来将MyService标记为Spring容器中的组件(即将MyService加入到IOC容器中,被其管理)  -->
        <bean id="myService" class="com.myh.chapter_03.config.MyService"/>
    
    </beans>
    

    beans.xml配置文件 是使用传统Spring框架 XML方式编写配置文件,在该配置文件中通过 <bean>标签MyService 标注为Spring容器中的 Bean 组件 ( 将该类加入到IOC容器中,被IOC容器管理 )。


    Chapter03Application.java ( 主程序启动类 ) :

    package com.myh.chapter_03;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.context.annotation.ImportResource;
    
    @SpringBootApplication //标记该类为"主程序启动类"
    //加载“自定义配置的.xml文件”的位置
    @ImportResource("classpath:beans.xml")
    public class Chapter03Application {
    
        public static void main(String[] args) {
            SpringApplication.run(Chapter03Application.class, args);
        }
    }
    

    (3编写完 Spring 的XML配置文件后,SpringBoot默认无法识别的,为了保证XML配置文件生效,需要在 项目启动类上 添加 @lmportResource( )注解 来指定XML 文件位置让该配置文件生效


    Chapter03ApplicationTests3.java ( 单元测试类 ):

    package com.myh.chapter_03;
    
    import com.myh.chapter_03.domain.MyProperties;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.context.SpringBootTest;
    import org.springframework.context.ApplicationContext;
    import org.springframework.test.context.junit4.SpringRunner;
    
    @RunWith(SpringRunner.class)
    @SpringBootTest //标记该类为“单元测试类”,并加载项目的上下文环境ApplicationContext
    public class Chapter03ApplicationTests3 {
    
        @Autowired
        private ApplicationContext applicationContext;
    
        @Test
        public void iocTest() {
            System.out.println(applicationContext.containsBean("myService"));
        }
    }
    

    执行 iocTest( )方法查看控制台输出效果
    在这里插入图片描述

    从上图可以看出,测试方法iocTest( )运行成功,输出结果true 表示 Spring 容器中已经包含了 id 为 myService实例说明 @lmportResource注解成功加载了 Spring 框架的XML配置文件

使用@Configuration( )注解编写自定义配置类

  • Spring Boot引入 自定义的XML配置文件这种配置方式在实际开发中的特殊情况下才会使用。在Spring Boot开发中,“约定大于配置”的思想,更推荐使用配置类方式代替 XML 配置。使用 @Configuration( )注解 (该注解配合 @Bean( ) 注解使用 )可以 指定配置类,它的作用和XML配置是一样的。

  • 配置类@Bean( )注解 方法 返回的“对象” 都将 作为Bean注入Spring容器,并且默认情况下,使用 @Bean( )注解方法名 就是 组件名

    @Bean( )注解将方法“返回的对象”交给 IOC容器管理默认情况下,方法名就是“组件名

  • 例子如

    MyService.java

    package com.myh.chapter_03.config;
    public class MyService {
    }
    

MyConfig.java :

package com.myh.chapter_03.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration //标记该类为“配置类”,同时将该类交给IOC容器管理
public class MyConfig {

    @Bean //该注解的作用: ①将方法的返回对象交给IOC容器管理 ②默认情况下,方法名就是“组件名”
    public MyService myService() {
        return new MyService();
    }
}

MyConfig@Configuration( )注解 声明的配置类( 类似于声明了一个XML配置文件),该配置类被Spring Boot 自动扫描识别;使用 @Bean 注解myService( )方法其返回值对象 会作为组件添加Spring 容器中( 类似于XML配置文件中的<bean>标签配置 ),并且该组件的id 默认方法名 : myService。


Chapter03ApplicationTests4.java :

package com.myh.chapter_03;
import com.myh.chapter_03.domain.MyProperties;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.ApplicationContext;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@SpringBootTest //标记该类为“单元测试类”,并加载项目的上下文环境ApplicationContext
public class Chapter03ApplicationTests4 {

    @Autowired
    private ApplicationContext applicationContext;
        @Test
    public void iocTest() {
        System.out.println(applicationContext.containsBean("myService"));
    }
}

执行 iocTest( )方法查看控制台输出效果
在这里插入图片描述

上图可以看出,测试方法iocTest( )运行成功,显示运行结果为true,表示 Spring 容器中已经包含了id为myService实例对象组件,说明使用 自定义配置类 ( 用 @Configuration注解 进行 配置 )的方式同样可以向Spring容器添加配置组件

4. Profile”多环境配置“ (满足“多种环境”的需求)

  • 在实际开发中,应用程序 通常 需要部署到不同的运行环境 中,如 开发环境测试环境生产环境等。不同的环境可能需要不同的环境配置,针对这种情况,显然手动修改配置文件适应不同开发环境的做法是不太现实的,此时通常会对项目进行多环境配置
  • SpringBoot框架提供了两种多环境配置的方式,分别是 :
    “Profile文件” 多环境配置 “@Profile注解” 多环境配置

使用“Profile文件”进行“多环境配置” ( resources目录下创建“Profile文件” + “全局配置文件”中激活“指定环境”的“配置文件”)

  • 使用 Profile文件 进行 多环境配置Spring Boot 框架中,使用Profile配置文件进行多环境配置时,该 配置文件名必须满足 : application-{profile}.properties 的格式,其中 {profile) 对应 具体的环境标识。这里以开发环境测试环境生产环境为例,编写对应环境的 配置文件示例代码如下 :

( resources目录创建这些“配置文件”)

application-dev.properties  //开发环境配置文件
application-test.properties //测试环境配置文件
application-prod.properties //生产环境配置文件
  • 如果 想要使用上述对应环境配置文件,只需要在SpringBoot全局配置文件激活 “指定环境”的 配置文件即可。例如,在 控制台 执行下列命令 激活环境配置 :
java -jar xxx.jar --spring.profiles.active=dev

除了在 控制台使用命令激活指定环境方式,还可以在 项目全局配置文件中配置springprofiles.active 属性激活配置。这里以激活 dev开发环境配置文件 为例,在全局配置文件application.properties配置激活环境属性示例代码如下 :

# 激发开发环境的配置文件 (通过该配置激活“指定环境”的“配置文件”)
spring.profiles.active=dev
  • 例子如 :

    第一步
    打开resources目录,在该目录下按照Profile文件命名规则创建不同运行环境对应的配置文件,这里分别创建 application-dev.propertiesapplication-test.propertiesapplication-prod.properties 多环境配置文件,并在各个配置文件中对服务端口进行不同的设置 :
    application-dev.properties :

    sever.port=8081
    

    application-test.properties :

    sever.port=8082
    

    application-prod.properties :

    sever.port=8083
    

    Spring Boot项目中,程序内部默认端口8080 ,而上述示例中通过 Profile文件进行了多环境配置不同的运行环境设置了不同的服务端口号。其中,application-dev.properties开发环境中,设置服务端口号为:8081 application-test.properties测试环境中,设置服务端口号为 :8082; application-prod.properties生产环境中,设置服务端口号为8083


    第二步
    打开的resources目录下的全局配置文件 application.properties,在该配置文件中配置 spring.profiles.active属性 选择性 激活Profile文件 设置示例代码如下 :

    application.properties

    #指定要激活的“指定环境”的“配置文件”
    spring.profiles.active=dev
    

    第三步
    运行 “主程序启动类” ,控制台输出内容如下 :
    在这里插入图片描述

    从上图可以看出,程序正常启动,并 显示服务启动的端口号8081,这与 选择激活的配置文件application-dev.properties端口号一致,说明 Profile多环境配置文件生效。如果想使用 Profile 文件 激活其他环境,可以在全局配置文件 application.properties中设置对应的配置文件重启项目查看效果。

使用“@Profile注解”进行“多环境配置” (创建类,在类下使用@Profile( )注解来标记该类作为一个“Profile文件” + “全局配置文件”中激活“指定环境”的“配置文件”)

  • 除了使用 Profile文件进行多环境配置,还可以使用 @Profile注解进行多环境配置

  • @Profile( )注解主要作用于“类”主要操作有
    通过 value属性 指定 配置环境( 等同于 Profile文件名称中的profile 值 )。 使用 @Profile注解配置环境,同样需要在 全局配置文件激活

  • 例子如 :

    DBController.java (接口):

    package com.myh.chapter_03.config.controller;
    
    import com.myh.chapter_03.config.DBConnector;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    public class DBController {
    
        @Autowired
        private DBConnector dbConnector;
    
        @GetMapping("/showDB")
        public void showDB() {
            dbConnector.configure();
        }
    }
    

    DBController接口的“三个实现类” :

    DevDBConnector.java (实现类):

    package com.myh.chapter_03.config.Impl;
    
    import com.myh.chapter_03.config.DBConnector;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.Profile;
    
    @Configuration
    @Profile("dev") //指定多环境配置类标识 (开发环境),通过在全局配置文件中指定dev来使用该环境配置
    public class DevDBConnector implements DBConnector {
    
        @Override
        public void configure() {
            System.out.println("数据库配置环境dev");
        }
    }
    
    

    ProdDBConnector.java (实现类):

    package com.myh.chapter_03.config.Impl;
    
    import com.myh.chapter_03.config.DBConnector;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.Profile;
    
    @Configuration
    @Profile("dev") //指定多环境配置类标识 (开发环境),通过在全局配置文件中指定dev来使用该环境配置
    public class DevDBConnector implements DBConnector {
    
        @Override
        public void configure() {
            System.out.println("数据库配置环境dev");
        }
    }
    
    

    TestDBConnector.java (实现类):

    package com.myh.chapter_03.config.Impl;
    
    import com.myh.chapter_03.config.DBConnector;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.Profile;
    
    /**
     * @author 莫月辉
     * @desctiption
     * @since 2024/3/27 23:24
     */
    @Configuration
    @Profile("test") //指定多环境配置类标识 (测试环境)
    public class TestDBConnector implements DBConnector {
        @Override
        public void configure() {
            System.out.println("数据库配置环境test");
        }
    }
    

    上述三个实现类都使用了 @Configuration注解@Profile注解,其中,@Configuration注解将实
    现类 声明为配置类,可以保证Spring Boot 自动扫描并识别 ( 将给类交给IOC容器管理 );@Profile注解用于进行 多环境配置,并 通过属性 标识 配置环境


    application.properties :

    #指定要激活的“指定环境”的“配置文件”
    spring.profiles.active=dev
    

    全局配置文件 application.properties 中设置 spring.profiles.active属性激活使用 @Profile注解构建的多环境配置


    DBController.java :

    package com.myh.chapter_03.config.controller;
    
    import com.myh.chapter_03.config.DBConnector;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    public class DBController {
    
        @Autowired
        private DBConnector dbConnector;
    
        @GetMapping("/showDB")
        public void showDB() {
            dbConnector.configure();
        }
    
    }
    

    @Autowired注解用于注入DBConnector,@GetMapping(“/showDB”)注解用于映射 GET 请求,这里用来映射路径为“/showDB”的请求


    运行“主程序启动类”,控制台输出效果 为 :

    在这里插入图片描述

    从上图可以看出,程序能够正常启动,并且控制台显示dev开发环境端口号是8081,说明通过 Profile文件配置的多环境 仍然在生效

    接着,在 浏览器上访问“http://localhost:8081/showDB”,查看控制台输出效果,结果如下图所示

    在这里插入图片描述

    从上面运行结果可以看出控制台的端口号8081,并打印出 指定标识为dev数据库配置信息,也就是说 程序执行数据库连接配置方法configure( )。由此可知无论使 用Profile 文件 还是 @Profile 注解 类都 可以进行多环境配置,而且 相互之间不会干扰

5. “随机值设置”以及“参数间引用”

  • SpringBoot配置文件设置属性 时,除了可以像前面示例中显示配置属性值,还可以使用随机值参数间引用“属性值”进行设置

随机值设置

  • SpringBoot配置文件,随机值设置使用到了Spring Boot 内嵌的 RandomValuePropertySource类,对一些 隐秘属性值 或者 测试用例属性值进行随机值注入

  • 随机值设置的 “语法格式”${random.xx}xx表示需要指定生成随机数类型范围,它可
    生成随机的整数通用唯一识别码(UUID)字符串示例代码如下 :

    #对属性值进行“随机值注入”
    my.string = ${random.value}    //配置随机字符串
    my.number = ${random.int}      //配置随机整数
    my.bignumber = ${random.long}  //配置随机long类型数
    my.uuid = ${random.uuid}      //配置随机UUID类型数
    my.number.than.ten = ${random.int(10)}  //配置小于10的随机整数
    my.number.in.range = ${random.int[1024,65536]}  //配置范围在[1024,65536]之间的随机整数
    

    上述代码中,使用 RandomValuePropertySource类中random提供的随机数类型,分别展示了 不同类型随机值设置示例

参数间引用

  • SpringBoot配置文件中,配置文件的属性值还可以进行参数间的引用也就是说先前定义的属性 可以被引用,并且配置文件可以解析引用的属性值。使用参数间引用的 好处就是,在多个具有相互关联配置属性中,只需要对其中一处属性预先配置,其他地方都可以引用,省去了后续多处修改的麻烦。

  • 参数间引用的语法格式${xx}xx 表示先前在 配置文件已经配置过的属性名示例代码

    app.name = MyApp
    add.description = ${app.name}
    

    上述 参数间引用设置示例中,先设置了“app.name=MyApp”,将app.name属性属性值设置为MyApp;接着,在app.description属性配置中,使用 ${app.name}对前一个属性值进行了引用

  • 例子如

    application.properties

    #随机值设置以及参数间引入配置
    tom.age = ${random.int[10,20]}
    tom.description = Tom的年龄可能是${tom.age}
    

    在上述 application.properties配置文件中,先 使用随机值设置tom.age属性属性值,该属性值设置在了[10,20]之间,随后使用参数间引用配置了tom.description 属性


    Chapter03ApplicationTests5.java ( 单元测试类 ) :

    package com.myh.chapter_03;
    
            import com.myh.chapter_03.domain.MyProperties;
            import org.junit.Test;
            import org.junit.runner.RunWith;
            import org.springframework.beans.factory.annotation.Value;
            import org.springframework.boot.test.context.SpringBootTest;
            import org.springframework.test.context.junit4.SpringRunner;
    
    @RunWith(SpringRunner.class)
    @SpringBootTest //标记该类为“单元测试类”,并加载项目的上下文环境ApplicationContext
    public class Chapter03ApplicationTests5 {
    
        //使用@Value注解 + 参数间引用 来该属性注入“属性值”
        @Value("${tom.description}")
        private String description;
    
        @Test
        public void placeholderTest() { //运行该方法
            System.out.println(description);
        }
    }
    

    需要说明的是,由于 属性description 引用属性 age 的值age 是[10,20]范围的随机值,因此执行placeholderTest( )方法输出的结果将是 [10,20]范围某个值

本文含有隐藏内容,请 开通VIP 后查看

网站公告

今日签到

点亮在社区的每一天
去签到