目录
使用 @ConfigurationProperties(批量注入):
长例(application.properties&application.yml)
配置文件值注入
现在来讲一讲SpringBoot使用配置文件注入时的两种操作:
功能 | @ConfigurationProperties | @Value |
---|---|---|
批量注入配置文件中的属性 | 支持 | 不支持 |
一个个指定 | 不支持 | 支持 |
松散绑定(松散语法) | 支持 | 不完全支持 |
SpEL | 不支持 | 支持 |
JSR303数据校验 | 支持 | 不支持 |
复杂类型封装 | 支持 | 不支持 |
现在逐一讲解上面的例子:
1.批量注入 vs 单个指定
使用 @ConfigurationProperties
(批量注入):
配置文件(application.properties):
app.name=MyApp
app.timeout=30
app.database.host=localhost
app.database.port=5432
Java代码:
package com.qcby.entity;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Component
@ConfigurationProperties(prefix = "app")
public class AppConfig {
private String name;
private int timeout;
private DatabaseConfig database;
// Getters and Setters
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getTimeout() {
return timeout;
}
public void setTimeout(int timeout) {
this.timeout = timeout;
}
public DatabaseConfig getDatabase() {
return database;
}
public void setDatabase(DatabaseConfig database) {
this.database = database;
}
public static class DatabaseConfig {
private String host;
private int port;
// Getters and Setters
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
}
@Override
public String toString() {
return "AppConfig{" +
"name='" + name + '\'' +
", timeout=" + timeout +
", database=" + database +
'}';
}
}
使用 @Value
(单个指定):
配置文件(application.properties):
app.name=MyApp
app.timeout=30
app.database.host=localhost
app.database.port=5432
Java代码:
package com.qcby.entity;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class AppConfig {
@Value("${app.name}")
private String name;
@Value("${app.timeout}")
private int timeout;
@Value("${app.database.host}")
private String databaseHost;
@Value("${app.database.port}")
private int databasePort;
// Getters and Setters
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getTimeout() {
return timeout;
}
public void setTimeout(int timeout) {
this.timeout = timeout;
}
public String getDatabaseHost() {
return databaseHost;
}
public void setDatabaseHost(String databaseHost) {
this.databaseHost = databaseHost;
}
public int getDatabasePort() {
return databasePort;
}
public void setDatabasePort(int databasePort) {
this.databasePort = databasePort;
}
@Override
public String toString() {
return "AppConfig{" +
"name='" + name + '\'' +
", timeout=" + timeout +
", databaseHost='" + databaseHost + '\'' +
", databasePort=" + databasePort +
'}';
}
}
对比:
-
@ConfigurationProperties
允许一次性注入整个对象,适用于复杂的配置结构。 -
@Value
需要为每个属性单独指定,适用于简单的配置或单个属性的注入。
2.松散绑定
Java中常见命名规则有驼峰命名法(
camelCase
)、蛇形命名法(snake_case
)、烤肉串命名法(kebab-case
),而松散绑定支持这三种名字互通,就比如配置文件里的my.feature.time-out
会自动绑定到FeatureConfig
类的timeout
属性上,Spring Boot 会处理这种命名风格的差异。使用注解时,在处理复杂情况时,
@Value
的匹配度就不如@ConfigurationProperties好。
3.SpEL
SpringEL表达式在@Value中的格式:@Value("#{表达式内容}")
@Value
配置文件
app.timeout=30
Java代码
@ConfigurationProperties
配置文件

Java代码

4.JSR303 数据校验
常用注解
@NotNull
:验证属性不能为null
。@NotEmpty
:验证字符串不为空字符串,也不能为null
;对于集合、数组等,验证其元素个数不为 0。@NotBlank
:验证字符串不为空字符串,且去除首尾空格后长度大于 0,常用于验证用户输入的非空字符串。@Size(min, max)
:验证字符串长度、集合大小、数组长度等在指定的最小值和最大值之间。@Digits(integer, fraction)
:验证属性是数字,且整数部分和小数部分的位数在指定范围内。@Pattern(regexp)
:验证字符串是否匹配指定的正则表达式常用
使用@ConfigurationProperties:
配置文件:
Java代码
package com.qcby.entity;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import org.springframework.validation.annotation.Validated;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
@Component
@ConfigurationProperties(prefix = "app")
@Validated //要想使用校验,一定不能忘了加这个注解
public class AppConfig {
@NotNull
private String name;
@Min(10)
private int timeout;
// getters and setters
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getTimeout() {
return timeout;
}
public void setTimeout(int timeout) {
this.timeout = timeout;
}
@Override
public String toString() {
return "AppConfig{" +
"name='" + name + '\'' +
", timeout=" + timeout +
'}';
}
}
注意这里:
访问结果:
长例(application.properties&application.yml)
使用@ConfigurationProperties注入
普通注入(长例)
Person类:
package com.qcby.entity;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.stereotype.Component;
import org.springframework.validation.annotation.Validated;
import javax.validation.constraints.Email;
import java.util.Date;
import java.util.List;
import java.util.Map;
@Component
@ConfigurationProperties(prefix = "person") //表示书写在application.properties里的前缀
@Validated //校验(有这个,才能实现下面@Email和@DateTimeFormat注解)
public class Person {
@Email //要求注入满足邮箱格式
private String lastName;
private Integer age;
private Boolean boss;
@DateTimeFormat(pattern = "yyyy-MM-dd") // 指定日期格式
private Date birth;
private Map<String, Object> maps;
private List<Object> lists;
private Dog dog;
// Getters and Setters
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Boolean getBoss() {
return boss;
}
public void setBoss(Boolean boss) {
this.boss = boss;
}
public Date getBirth() {
return birth;
}
public void setBirth(Date birth) {
this.birth = birth;
}
public Map<String, Object> getMaps() {
return maps;
}
public void setMaps(Map<String, Object> maps) {
this.maps = maps;
}
public List<Object> getLists() {
return lists;
}
public void setLists(List<Object> lists) {
this.lists = lists;
}
public Dog getDog() {
return dog;
}
public void setDog(Dog dog) {
this.dog = dog;
}
@Override
public String toString() {
return "Person{" +
"lastName='" + lastName + '\'' +
", age=" + age +
", boss=" + boss +
", birth=" + birth +
", maps=" + maps +
", lists=" + lists +
", dog=" + dog +
'}';
}
}
Dog类:
package com.qcby.entity;
public class Dog {
private String name;
private Integer age;
// Getters and Setters
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "Dog{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
编写一个Controller类:
package com.qcby.controller;
import com.qcby.entity.Person;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class PersonController {
@Autowired
private Person person;
@GetMapping("/person")
public Person getPerson() {
System.out.println(person.toString());
return person;
}
}
用application.properties配置文件实现:
spring.application.name=sbdemotest01
server.port=8080
#这里表示配置8080端口为这个项目使用
person.last-name=example@example.com
person.age=30
person.boss=true
person.birth=2000-01-01
person.maps.key1=value1
person.maps.key2=value2
person.lists[0]=item1
person.lists[1]=item2
person.dog.name=Tom
person.dog.age=5
或是用application.yml文件编写:
spring:
application:
name: sbdemotest01
server:
port: 8080
person:
last-name: example@example.com
age: 30
boss: true
birth: 2000-01-01
maps:
key1: value1
key2: value2
lists: [item111, item222]
dog:
name: Tom
age: 5
my:
feature:
enabled: true
timeout: 3000
实现上面操作后,就可以通过访问“localhost:8080/person”来获取结果: