【SpringBoot】第2章 SpringBoot核心配置与注解

学习目标

  • 熟悉SpringBoot全局配置文件的使用

  • 熟悉SpringBoot自定义配置

  • 掌握SpringBoot配置文件属性值注入

  • 掌握Profile多环境配置

  • 了解随机值设置以及参数间引用

2.1 全局配置文件

全局配置文件能够对一些默认配置进行修改。SpringBoot使用一个application.properties或者application.yaml的文件作为全局配置文件,该文件存放在src/main/resource目录或者类路径的/config,一般会选择resource目录。本节将针对这两种全局配置文件进行讲解。

2.1.1 application.properties配置文件

使用Spring Initializr方式构建SpringBoot项目时,会在resource目录下自动生成一个空的application.properties文件,SpringBoot下古墓启动时会自动加载application.properties文件。

我们可以在application.properties文件中定义SpringBoot项目的相关属性,当然,这些相关属性可以时系统属性,环境便利,命令参数等信息,也可以是自定义配置文件名称和位置。

接下来我们通过一个案例对SpringBoot项目中application.properties配置文件的具体使用进行讲解。

(1)使用Spring Initializr方式创建一个SpringBoot项目,定义号包名,选择Web依赖。

(2)为了方便查看application.properties配置文件属性配置的效果,我们在包下创建domain包,并在该包下创建两个实体类Pet和Person。

Pet.java

package com.yhh.domain;/*** 宠物实体类*/
public class Pet {private String type;private String name;public Pet() {}public Pet(String type, String name) {this.type = type;this.name = name;}@Overridepublic String toString() {return "Pet{" +"type='" + type + '\'' +", name='" + 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;}
}

Person.java

package com.yhh.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;/*** 人类实体类*/
//用于将Person类作为Bean注入Spring容器
@Component
//将配置文件中以person开头的属性注入该类中
@ConfigurationProperties(prefix = "person")
public class Person {private int id;private String name;private List hobby;//爱好private String[] family;//家庭成员private Map map;private Pet pet;//宠物public Person() {}public Person(int id, String name, List hobby, String[] family, Map map, Pet pet) {this.id = id;this.name = name;this.hobby = hobby;this.family = family;this.map = map;this.pet = pet;}@Overridepublic String toString() {return "Person{" +"id=" + id +", name='" + name + '\'' +", hobby=" + hobby +", family=" + Arrays.toString(family) +", map=" + map +", 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;}
}

准备了两个实体类文件,后续我们会演示将application.properties配置文件中的自定义配置属性注入Person实体类的对应属性中。其中,@ConfigurationProperties(prefix = "person")注解的作用是将配置文件中以person开头的属性值通过seter方法注入实体类对应属性中,@Component注解的作用是将当前注入属性值的Person类对象作为Bean组件放到Spring容器中,只有这样它才能被@ConfigurationProperties注解赋值。

在上述自定义Person类中,添加了一个@Component注解,将该自定义类作为Spring容器的组件,其根本目的是让SpringBoot可以自动扫描到该组件,然后进行其他功能实现。而如果想要将一个自定义类添加为Spring容器的组件,除了可以使用@Component注解外,还可以使用@Controller,@Service,@Repository,@Configuration等注解,分别用于控制层类,业务逻辑层类,数据访问层类以及全局配置类等。

(3)打开项目的resources目录下的application.properties配置文件,在该配置文件中编写需要对Person类设置的配置属性

# 对实体类对象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=kitty

在SpringBoot默认全局配置文件application.properties中通过“person.xx”对Person的相关属性进行了配置,这些配置属性会通过@ConfigurationProperties(prefix="person")注解注入Person实体类的对应属性中。

在编写application.properties配置文件时,由于要配置的Person对象属性时我们自定义的,SpringBoot无法自动识别,所以不会有任何书写提示。在实际开发中,为了出现代码提示的效果来方便配置,在使用@ConfigurationProperties注解进行配置文件属性值注入时,可以在pom.xml文件中添加一个SpringBoot提供的配置处理器依赖

<!--配置处理器依赖--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-configuration-processor</artifactId><optional>true</optional></dependency>

在pom.xml中添加上述配置依赖后,还需要重新运行项目启动类或者使用“Ctrl+F9”组合键(即BuildProject)重构当前项目方可生效。

为了查看application.properties配置文件是否正确,同时查看属性配置效果,在项目的测试类中引入Person实体类对象,并进行输出测试。

package com.yhh;import com.yhh.controller.MyController;
import com.yhh.domain.Person;
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;/*** 使用SpringInitializr方式自动创建的主程序启动类对应的单元测试类*/
@RunWith(SpringRunner.class)
@SpringBootTest
public class DemoApplicationTests {@AutowiredPerson person;@Testpublic void printPerson(){System.out.println(person);}@Testpublic void contextLoads() {}}

可在控制台观察到数据的显示和打印输出。

2.1.2 application.yaml配置文件

YAML文件格式是SpringBoot支持的一种JSON超集文件格式,相较于传荣的Properties配置文件,YAML文件以数据为核心,是一种更为直观且容易被计算机识别的数据序列化格式。application.yaml配置文件的工作原理和application.properties是一样的,只不过YAML格式配置文件看起来更简洁一些。

application.yaml文件使用“key:(空格)value”格式配置属性,使用缩进控制层级关系。

这里我们针对不同数据类型的属性值,介绍以下YAML文件配置属性的写法:

(1)value值为普通数据类型(如数字,字符串,布尔等)

当YAML配置文件中配置的属性值为普通数据类型时,可以直接配置对应的属性值,同时对于字符串类型的属性值,不需要额外添加引号

server:port:8081path:/hello

(2)value值为数组和单列集合

当YAML配置文件中配置的属性值为数组或单列结合类型时,主要有两种书写方式:缩进式写法和行内式写法。

其中缩进式写法还有两种表示形式

person:hobby:- play- read- sleep

或者是如下形式:

person:hobby:play,read,sleep

上述代码使用两种缩进式写法为person对象的属性hobby赋值,其中一种是通过“-(空格)属性值”的形式为属性赋值,另外一种是直接赋值并使用英文逗号分隔属性值。

在YAML配置文件中,还可以将上述缩进式写法简化为行内式写法

person:hobby:[play,read,sleep]

在yaml配置文件中,行内式的写法显然比缩进是更加简便。使用行内式写法设置属性值时,中括号"[]"时可以省略的,程序会自动匹配校对属性的值。

(3)value值为Map集合和对象

当YAML配置文件中配置的属性值为Map集合或对象类型时,YAML配置文件格式同样可以分为两种书写方式:缩进式写法和行内式写法。

缩进式写法

person:map:k1:v1k2:v2

行内式写法

person:map:{k1:v1,k2:v2}

在YAML配置文件中,配置的属性值为Map集合或对象类型时,缩进式写法的形式按照YAML文件格式编写即可,而行内式写法的属性值要用大括号“{}”包含。

接下来我们演示使用yaml文件为Person对象赋值

在该项目的resources目录下创建application.yaml配置文件,在该配置文件中设置Person对象的属性值

# 对实体类对象Person进行属性配置
person:id: 2name: 张三hobby: [sing,read,sleep]family: [father,mother]map: {k1: v3,k2: v4}pet: {type: cat,name: tom}

这些配置的属性将会通过@ConfigurationProperties(prefix = "person")注解注入Person实体类的对应属性中。

接下来再次通过单元测试类进行测试访问,我们会发现输出打印的结果还是properties中赋值的属性值,这是因为在SpringBoot项目中properties文件优先级高于yaml文件。因此我们将properties文件中的属性值进行注释,再次测试即可。

通过两种方式的对比,我们发现yaml文件的方式更简洁,因此我们后期都使用yaml文件的方式进行配置赋值。

2.2 配置文件属性值的注入

2.2.1 使用@ConfigurationProperties注入属性

SpringBoot提供的@ConfigurationProperties注解用来快速,方便的将配置文件中的自定义属性值批量注入某个Bean对象的多个对应属性中。假设现在有一个配置文件,使@ConfigurationProperties注入配置文件的属性

需要注意的是,使用@ConfigurationProperties注解批量注入属性值时,要保证配置文件中的属性与对应实体类的属性名一致,否则无法正确获取并注入属性值。

2.2.2 使用@Value注入属性

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

在domain包中创建一个Student.java

package com.yhh.domain;import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;@Component
public class Student {@Value("10")private int id;//学号@Value("${person.name}")private String name;private String phone;private String sex;private String address;private int age;@Overridepublic String toString() {return "Student{" +"id=" + id +", name='" + name + '\'' +", phone='" + phone + '\'' +", sex='" + sex + '\'' +", address='" + address + '\'' +", age=" + age +'}';}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 String getPhone() {return phone;}public void setPhone(String phone) {this.phone = phone;}public String getSex() {return sex;}public void setSex(String sex) {this.sex = sex;}public String getAddress() {return address;}public void setAddress(String address) {this.address = address;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public Student(String phone, String sex, String address, int age) {this.phone = phone;this.sex = sex;this.address = address;this.age = age;}public Student() {}
}

在单元测试类中测试一下:

package com.yhh;import com.yhh.controller.MyController;
import com.yhh.domain.Person;
import com.yhh.domain.Student;
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;/*** 使用SpringInitializr方式自动创建的主程序启动类对应的单元测试类*/
@RunWith(SpringRunner.class)
@SpringBootTest
public class DemoApplicationTests {@AutowiredStudent student;@Testpublic void printStudent(){System.out.println(student);}}

测试结果如下

2.2.3 两种注解对比分析

下面我们针对以上两种属性值注入的方式进行对比

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

具体说明如下:

  1. 底层框架

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

  2. 功能

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

  3. 属性setter方法

    在使用@ConfigurationProperties注解进行配置文件属性值读取注入时,还必须为每一个属性设置setter方法,通过对应的注解才能够将配置文件中的属性一一匹配并注入对应的Bean属性上。如果配置文件中没有配置属性值,则会自动将对应的Bean属性设置为空。

  4. 复杂类型属性注入

    @ConfigurationProperties和@Value都能注入配置文件中的属性,不同的是,@ConfigurationProperties支持任意数据类型的属性注入,包括基本数据类型和复杂数据类型,而@Value只能注入基本类型的属性。

  5. 松散绑定

    @ConfigurationProperties注解进行配置文件属性值注入时,支持松散绑定语法

person.firstName=james
person.first-name=james
person.first_name=james
PERSON.FIRST_NAME=james

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

       6. JSR303数据校验

@ConfigurationProperties注解进行配置文件属性值注入时,支持JSR303数据校验,其主要作用时校验配置文件中注入对用Bean属性的值时否符合相关值的规则

package com.yhh.domain;import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import org.springframework.validation.annotation.Validated;import javax.validation.constraints.Email;@Component
@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数据校验。

7.SpEL表达式

@Value注解注入配置文件属性时,支持SpE来表达是语法,即“#{xx}”

@Value("#{5*2}") //使用@Value注解的SpEL表达式直接为属性注入值
private int id;

以上代码在不适用配置文件的情况下,只有@Value注解可以使用。

对于以上两种方式的分析,在实际开发中该如何选择?需要对单个属性进行赋值时使用@Value,需要对大量的属性赋值时使用@ConfigurationProperties注解。

2.3 SpringBoot自定义配置

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

2.3.1 使用@PropertySource加载配置文件

如果要加载自定义配置文件,可以使用@PropertySource和@Configuration注解实现。@PropertySource注解可以指定自定义配置文件的位置和名称,@Configuration注解可以将实体类指定为自定义配置类。如果需要将自定义配置文件中的属性值注入实体类属性,可以使用@ConfigurationProperties或@Value注入属性值。

接下来我们来演示一下该注解的使用,我们在resouces目录下创建一个test.properties自定义配置文件

# 对实体类对象MyProperties进行属性配置
test.id=110
test.name=test

在domain包下创建MyProperties类

package com.yhh.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 //自定义配置类
@PropertySource("classpath:test.properties")//指定自定义配置文件位置和名称
@EnableConfigurationProperties(MyProperties.class)//开启对应配置类的属性注入功能
@ConfigurationProperties(prefix = "test")//指定配置文件注入属性前缀
public class MyProperties {private int id;private String name;@Overridepublic String toString() {return "MyProperties{" +"id=" + id +", name='" + 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;}
}

@Configuration注解用于表示当前类时一个自定义配置类,该类会作为Bean组件添加到Spring容器中,这里等同于@Conponent注解。

@PropertySource("classpath:test.properties")注解指定了自定义配置文件的位置和名称,此代码表示自定义配置文件为classpath类路径下的test.properties文件。

@ConfigurationProperties(prefix = "test")注解将上述自定义配置文件test.properties中的test开头的属性值注入该配置类属性中。

@EnableConfigurationProperties(MyProperties.class)注解表示开启对应配置类MyProperties的属性注入功能,该注解时配合@ConfigurationProperties使用的。如果自定义配置类使用了@Component注解而非@Configuration注解,那么@EnableConfigurationProperties注解可以省略

接着我们可以在单元测试类中进行测试

package com.yhh;import com.yhh.controller.MyController;
import com.yhh.domain.MyProperties;
import com.yhh.domain.Person;
import com.yhh.domain.Student;
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;/*** 使用SpringInitializr方式自动创建的主程序启动类对应的单元测试类*/
@RunWith(SpringRunner.class)
@SpringBootTest
public class DemoApplicationTests {@AutowiredMyProperties myProperties;@Testpublic void printProperties(){System.out.println(myProperties);}}

2.3.2 使用@ImportResource加载XML配置文件

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

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

接下来我们演示代码,我们创建一个config包,并在该包下创建一个类MyService,该类中不需要编写任何代码

package com.yhh.config;public class MyService {
}

在resources目录下创建一个beans.xml的XML自定义配置文件,在该配置文件中将MyService配置为Bean

<?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 id="myService" class="com.yhh.config.MyService"></bean>
</beans>

编写玩Spring的XML配置文件后。SpringBoot默认时无法识别的,为了保证XML配置文件生效,需要在项目启动类上添加@ImportResource注解来指定XML文件位置

接下来我们在单元测试类中进行测试MyService类是否能被注入Spring容器中

通过显示,可以看到该类已被注入成功。

2.3.3 使用@Configuration编写自定义配置类

上一节讲解了如何在SpringBoot中引入自定义的XML配置文件,这种配置方式在实际开发中的特殊情况下才会使用。在SpringBoot开发中,“约定大于配置”的思想,更推荐使用配置类的方式代替XML配置。

使用@Configuration注解可以指定配置类,它的作用和XML配置是一样的,配置类中@Bean注解方法返回的对象都将作为Bean注入Spring容器,并且默认情况下,使用@Bean注解的方法名就是组件名。

下面我们来演示以下使用@Configuration编写自定义配置类的用法

在包下创建config包,新建一个类MyConfig,并使用@Configuration注解将该类声明一个配置类

package com.yhh.config;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class MyConfig {//将返回值对象作为组件添加到Spring容器中,该组件id默认为方法名@Beanpublic MyService myService(){return new MyService();}
}

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

接下来我们通过测试类来测试,测试之前需要将@ImportResource注解注释,配置类的方式是不需要该注解进行加载的。

2.4 Profile多环境配置

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

2.4.1 使用Profile文件进行多环境配置

在SpringBoot框架中,使用Profile配置文件进行多环境配置时,该配置文件名必须满足application-{profile}.properties的格式,其中{profile}对应具体的环境表示。这里以开发环境,测试环境和生产环境为例,编写对应环境的配置文件

application-dev.properties  //开发环境配置文件
application-test.properties  //测试环境配置文件
application-prod.properties  //生产环境配置文件

如果想要使用上述对应环境的配置文件,只需要在SpringBoot全局配置文件中激活指定环境的配置文件即可。例如,在控制台执行下列命令激活环境配置

java -jar xxx.jar --spring.profiles.active=dev

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

#激活开发环境配置文件
spring.profiles.active=dev

接下来我们演示代码,在resource目录下,按照Profile文件命名规则创建不同运行环境对应的配置文件,这里分别创建application-dev.properties,application-test.properties和application-prod.properties多环境配置文件,并在各个配置文件中对服务端口进行不同的设置

# 配置开发环境下端口号
server.port=8081
# 配置测试环境下端口号
server.port=8082
# 配置生产环境下端口号
server.port=8083

在SpringBoot项目中,程序内部默认端口为8080,而上述代码中通过Profile文件进行了多环境配置,不同的运行环境设置了不同的服务端口号。

打开resouces目录下的全局配置文件application.properties,在该配置文件中配置spring.profiles.active属性选择性激活Profile文件设置

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

为了查看使用Profile文件进行多环境配置的效果,直接启动项目的启动类,并查看控制台输出效果。

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

2.4.2 使用@Profile注解进行多环境配置

除了使用Profile注解继续宁多环境配置外,还可以使用@Profile注解进行多环境配置。@Profile注解主要作用于类,并通过value属性指定配置环境(等同于Profile文件名称中的profile值)。使用@Profile注解配置的环境,同样需要在全局配置文件中激活。

接下来我们通过项目进行演示,在config包下创建一个用于配置数据库的接口文件DBConnector

package com.yhh.config;public interface DBConnector {void configure();
}

接着在config包下创建三个实现了DBController接口的类DevController,TestController和ProdController并重写了configure()方法,分别模拟链接配置不同的数据库环境

package com.yhh.config;import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;@Configuration
@Profile("dev") //指定多环境配置类标识
public class DveConnector implements DBConnector {@Overridepublic void configure() {System.out.println("数据库配置环境dev");}
}
package com.yhh.config;import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;@Configuration
@Profile("test") //指定多环境配置类标识
public class TestConnector implements DBConnector {@Overridepublic void configure() {System.out.println("数据库配置环境test");}
}
package com.yhh.config;import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;@Configuration
@Profile("prod") //指定多环境配置类标识
public class ProdConnector implements DBConnector {@Overridepublic void configure() {System.out.println("数据库配置环境prod");}
}

上述三个实现类都使用了@Configuration和@Profile注解,其中,@Configuration注解将实现类声明为配置类,可以保证SpringBoot自动扫描并识别;@Profile注解用于进行多环境配置,并通过属性表示配置环境。

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

为了测试@Profile注解多环境配置的效果,在项目的controller包中创建一个表示数据库连接配置的DBController类进行测试

package com.yhh.controller;import com.yhh.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 {@AutowiredDBConnector connector;@GetMapping("/showDB")public void show(){connector.configure();}
}

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

启动项目的启动类,查看控制台输出显示端口的切换结果

接着在浏览器上访问“http://localhost:8081/showDB” 查看控制台输出效果

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

2.5 随机值设置以及参数间引用

在SpringBoot配置文件中设置属性时,除了可以像以上项目中显示的配置属性值外,还可以使用随机值和参数间引用对属性值进行设置。希迈纳我们针对配置文件中这两种属性值的设置方式及逆行详细讲解。

  1. 随机值设置

    在SpringBoot配置文件中,随机值设置使用到了SpringBoot内嵌的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.less.than.ten=${random.int(10)}  #配置小于10的随机整数
my.number.in.range=${random.int[1024,65536]} #配置范围在[1024,65536]之间的随机整数

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

        2. 参数见引用

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

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

app.name=MyApp
app.description=${app.name} is a SpringBoot application

在上述参数间引用设置代码中,先设置了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属性。

在项目的测试类中定义属性description属性,并使用@Value注解注入tom.description属性。

这里发现一个问题,测试类测试的时候加载application.properties文件中的中文数据会产生乱码,这里需要解决。

后来通过查询了很多资料,是说因为Springboot项目中@Value注解加载application.properties中的中文属性默认的编码格式为ISO-8859-1格式,需要将该格式转换成UTF-8格式,

String s = new String(description.getBytes("ISO-8859-1"), "UTF-8");

但并没有解决,最后还是在属性放置application.yaml文件中,应该该文件中的所有字符默认为UTF-8格式,因此就不存在中文乱码问题

# 对实体类对象Person进行属性配置
person:id: 2name: 张三hobby: [sing,read,sleep]family: [father,mother]map: {k1: v3,k2: v4}pet: {type: cat,name: tom}tom:age: ${random.int[10,20]}description: Tom 的年龄可能是${tom.age}

当多次运行,可以观察到age的值会在[10-20]之间产生随机数。

本章小结

本章主要讲解了SpringBoot的核心配置与注解,包括全局配置的使用,配置文件属性值的注入,SpringBoot自定义配置,多环境配置,随机值设置以及参数间引用。

习题

一、填空题

  1. 默认情况下,SpringBoot生产的全局配置文件( ).

  2. SpringBoot项目中,application.yaml文件使用( )格式配置属性。

  3. SpringBoot提供的( )注解可以批量将配置文件的属性注入Bean对象。

  4. 使用( )注解注入配置文件属性时,支持SpEL表达式语法。

  5. SpringBoot中能够使用( )注解进行多环境配置。

二、判断题

  1. application.yaml配置文件的属性类型只能时数组类型。( )

  2. 使用@ConfiggurationProperties注解注入属性值时,必须为对应的属性提供setter方法。( )

  3. @Value注解时SpringBoot提供的,用来读取配置文件的属性并能够批量注入Bean。( )

  4. @Value注解支持所有数据类型的属性读取和注入。( )

  5. SpringBoot可以使用@PropertiesResource注解引入XML配置文件。( )

三、选择题

  1. 下列关于SpringBoot全局配置文件的说法,正确的是( ).(多选)

    A.SpringBoot支持application.properties全局配置文件

    B.SpringBoot支持application.yaml全局配置文件

    C.SpringBoot支持application.yml全局配置文件

    D.SpringBoot全局配置文件必须在项目resouces根目录下

  2. 下列关于YAML配置文件的说法,正确的是( ).

    A.YAML配置文件的内容是“key:value”形式的键值对,并使用缩进式写法

    B.YAML配置文件的行内式写法配置单列集合属性,包含属性值的中括号“[]”可以省略

    C.YAML配置文件的行内式写法配置单列集合属性,包含属性值的中括号“{}”可以省略

    D.以上都不对

  3. 下列关于@ConfiggurationProperties注解的说法中,正确的是( ).

    A.@ConfiggurationProperties注解只能作用于类

    B.使用@ConfiggurationProperties注解为Bean注入属性时,必须为Bean设置seter方法

    C.@ConfiggurationProperties注解必须和@Componet结合使用

    D.要想使@ConfiggurationProperties注解注入的属性生效,必须使用@EnableConfigurationProperties注解开启注入

  4. 下列关于@ConfiggurationProperties和@Value注解的说法,正确的是( )

    A.@ConfiggurationProperties和@Value注解都是SpringBoot框架自带的

    B.进行属性值注入时,@ConfiggurationProperties和@Value注解配置中必须设置属性的setter方法

    C.@ConfiggurationProperties注解进行配置文件属性值注入时,支持JSR303数据校验

    D.@Value注解进行配置文件属性值注入时,支持松散绑定语法

  5. 下列关于SpringBoot的Profile多环境配置的说法,错误的是( ).

    A.SpringBoot提供了两种多环境配置的方式:Profile文件多环境配置和@Profile注解多环境配置

    B.Profile配置文件的名必须满足application-{profile}.properties的格式

    C.可以在项目全局配置文件中配置spring.profiles.active属性激活指定的多环境配置文件

    D.在多个自定义类上直接使用@Profile注解可以进行多环境配置

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/2660777.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

王道考研计算机网络——应用层

如何为用户提供服务&#xff1f; CS/P2P 提高域名解析的速度&#xff1a;local name server高速缓存&#xff1a;直接地址映射/低级的域名服务器的地址 本机也有告诉缓存&#xff1a;本机开机的时候从本地域名服务器当中下载域名和地址的对应数据库&#xff0c;放到本地的高…

开发Python网络爬虫应用,爬取链家新房楼盘信息保存到mongodb中,并分析相关数据

这里写自定义目录标题 爬取代码分析数据问题 爬取代码 import requests import time from lxml import html from pymongo import MongoClient import randomBASEURL https://cq.fang.lianjia.com/loupan/# 获取某市区域的所有链接 def get_areas(url):print(获取区县列表)# …

云手机引领社交平台运营新潮流

在网络高度发展的今天&#xff0c;社交平台已经成为企业宣传推广的关键渠道之一。传统的社交运营方式已经无法满足效率的要求&#xff0c;云手机因而开始引领社交平台运营的新潮流。本文将深入探讨云手机如何重新定义社交平台运营&#xff0c;为用户和企业带来更为便捷、智能的…

定期修改公司数据协议的重要性

目录 ​编辑 为公司和客户数据提供更好的安全性 利用现代数据分析工具 标准化您的数据收集流程 改善数据的使用 增强您的营销和销售活动 定义数据分类指南 创建更具凝聚力和协作性的团队 遵守法律法规 结论 企业主可以使用许多对其成功至关重要的工具&#…

[BUG] Hadoop-3.3.4集群yarn管理页面子队列不显示任务

1.问题描述 使用yarn调度任务时&#xff0c;在CapacityScheduler页面上单击叶队列&#xff08;或子队列&#xff09;时&#xff0c;不会显示应用程序任务信息&#xff0c;root队列可以显示任务。此外&#xff0c;FairScheduler页面是正常的。 No matching records found2.原…

计算机视觉与自然语言处理(Open AI)

1.语音识别技术 语音识别是将语音转换为文本的技术&#xff0c; 是自然语言处理的一个分支。通过特征的提取、模式的匹配将语音信号变为文本或命令&#xff0c;以实现机器识别和理解语音。 按照应用场景的不同&#xff0c;可以大致分为三类&#xff1b; • 电信级系统应用&…

VS配置PCO相机SDK环境

VS配置PCO相机SDK环境 概述:最近要用到一款PCO相机,需要协调其他部件实现一些独特的功能。因此需要用到PCO相机的SDK,并正确配置环境。良好的环境是成功的一半。其SDK可以在官网下载,选择对应版本的安装即可。这里用的是pco.cpp.1.2.0 Windows,VS 2022 专业版。 链接: P…

数据结构 day6 栈+队列+二分查找+插入排序

插入排序 #include <stdio.h> #include<string.h> #include<stdlib.h> int main(int argc, const char *argv[]) {int a[]{41,50,66,38,32,49,18};int nsizeof(a)/sizeof(a[0]);int i,j,t;for(i1;i<n;i){int ta[i];for(ji-1;j>0;j--){if(t<a[j]){a…

【MATLAB】交叉验证求光滑因子的广义神经网络时序预测算法

有意向获取代码&#xff0c;请转文末观看代码获取方式~也可转原文链接获取~ 1 基本定义 交叉验证求光滑因子的广义神经网络时序预测算法的基本原理如下&#xff1a; 首先&#xff0c;我们需要了解什么是交叉验证和光滑因子。交叉验证是一种评估模型性能的常用方法&#xff0c…

基于源码去理解Iterator迭代器的Fail-Fast与Fail-Safe机制

原创/朱季谦 在Java编程当中&#xff0c;Iterator迭代器是一种用于遍历如List、Set、Map等集合的工具。这类集合部分存在线程安全的问题&#xff0c;例如ArrayList&#xff0c;若在多线程环境下&#xff0c;迭代遍历过程中存在其他线程对这类集合进行修改的话&#xff0c;就可…

009:vue结合el-table实现表格行拖拽排序(基于sortablejs)

文章目录 1. 实现效果2. 安装 sortablejs 插件3. 完整组件代码4. 注意点 1. 实现效果 2. 安装 sortablejs 插件 sortablejs 更多用法 cnpm i --save sortablejs3. 完整组件代码 <template><div class"home"><div class"body"><el-ta…

可以加速 Pandas(即使在 CPU 环境中)而无需编码...... FireDucks

引言 使用 Pandas 处理大量数据时&#xff0c;是否曾因处理时间过长而感到沮丧&#xff1f; 显然&#xff0c;一个库已经发布&#xff0c;可以在不改变现有代码的情况下加速 Pandas。 由 NEC Laboratories 发布的名为 FireDucks 的库的 Beta 版本可以免费使用。 而且&#xff…

浅谈WPF之控件模板Control Template和数据模板Data Template

WPF不仅支持传统的Windows Forms编程的用户界面和用户体验设计&#xff0c;同时还推出了以模板为核心的新一代设计理念。在WPF中&#xff0c;通过引入模板&#xff0c;将数据和算法的“内容”和“形式”进行解耦。模板主要分为两大类&#xff1a;数据模板【Data Template】和控…

linux cat命令增加-f显示文件名功能

在使用cat命令配合grep批量搜索文件内容时&#xff0c;我仅仅能知道是否搜索到&#xff0c;不知道是在哪个文件里找到的。比如cat ./src/*.c | grep full_write,在src目录下的所有.c文件里找full_write,能匹配到所有的full_write&#xff0c;但是不知道它们分别在哪些文件里。于…

【八】【C语言\动态规划】1567. 乘积为正数的最长子数组长度、413. 等差数列划分、978. 最长湍流子数组,三道题目深度解析

动态规划 动态规划就像是解决问题的一种策略&#xff0c;它可以帮助我们更高效地找到问题的解决方案。这个策略的核心思想就是将问题分解为一系列的小问题&#xff0c;并将每个小问题的解保存起来。这样&#xff0c;当我们需要解决原始问题的时候&#xff0c;我们就可以直接利…

黑客攻击服务器之后如何清除痕迹?如何进行伪装和逃脱追踪?

黑客攻击服务器之后如何清除痕迹?如何进行伪装和逃脱追踪?附完整执行代码。 在攻击结束后,如何不留痕迹的清除日志和操作记录,以掩盖入侵踪迹,这其实是一个细致的技术活。你所做的每一个操作,都要被抹掉;你所上传的工具,都应该被安全地删掉。 黑客的一次攻击行为,主…

HarmonyOS应用开发-仿微信UI实现

在本篇博客中&#xff0c;介绍一个仿微信的 HarmonyOS 应用&#xff0c;应用包括微信的首页、通讯录、发现、我的页面&#xff0c;以及聊天界面。 一、先上效果图&#xff1a; 二、代码解读 以聊天界面为例&#xff0c;代码如下&#xff08;解读在代码下面&#xff09;&#…

【华为数据之道学习笔记】7-3基于物理世界的“硬感知”能力

“硬感知”能力的分类 数据采集方式主要经历了人工采集和自动采集两个阶段。自动采集技术仍在发展中&#xff0c;不同的应用领域所使用的具体技术手段也不同。基于物理世界的“硬感知”依靠的就是数据采集&#xff0c;是将物理对象镜像到数字世界中的主要通道&#xff0c;是构建…

STM32F407-14.3.10-表73具有有断路功能的互补通道OCx和OCxN的输出控制位-1x000-1x111(总结)

基于表73中&#xff0c;主输出使能&#xff08;MOE1&#xff09;的8种OCx与OCxN的输出状态及波形图&#xff0c;已经单独整理输出8篇文章&#xff0c;方便需要时单独回查。 主输出使能时&#xff08;MOE1&#xff09;总结如下 通过表73中可得以下结论 1、控制位1x000与1x100…

ffmpeg两种windows版本区别说明

版本一 必须拷贝exe和dll文件才能使用&#xff0c;如果缺少dll则exe不正正常执行 如果缺少dll &#xff0c;执行 exe会报错如下 版本2 直接拷贝exe就能使用&#xff0c;没有依赖的环境