目录
1. 简介
1.1 @value
在Spring Boot中,@Value注解是一个非常有用的特性,它允许我们将外部的配置(如application.properties或application.yml文件中的属性)注入到我们的Bean中。这对于读取配置信息,如数据库连接信息、服务地址等,非常有用。
基本用法
@Value注解可以应用于字段、setter方法或配置方法上。它使用SpEL(Spring Expression Language)表达式来读取配置值。
1.2 @ConfigurationProperties
@ConfigurationProperties 是 Spring Boot 提供的一个非常强大的注解,用于将配置文件中的属性绑定到 Java Bean 上。与 @Value 注解相比,@ConfigurationProperties 提供了更丰富的特性,比如松散绑定(relaxed binding)、JSR-303 数据校验以及复杂的类型绑定等。
基本用法
- 定义一个配置类:首先,你需要定义一个配置类,并使用 @ConfigurationProperties 注解来指定配置的前缀。
- 启用配置属性绑定:默认情况下,Spring Boot 会自动扫描带有 @ConfigurationProperties 注解的类,并将它们注册为 Spring 应用上下文中的 bean。但是,如果你想要精确地控制哪些配置类被注册,你可以在 @EnableConfigurationProperties 注解中指定它们。
- 在配置文件中设置属性:在 application.properties 或 application.yml 文件中设置与配置类属性相对应的配置项。
2. 使用
2.1 @value的使用
首先创建springboot的项目
创建application.yml
person: name : 岳轩子 sex : 雄 age : 18 birthday : 2002/2/31 maps : { k1 : 20 , k2 : 21} lists : [小黄 , 小黑] dog: name : 旺财
创建Person.java
import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import org.springframework.validation.annotation.Validated; import java.util.Date; import java.util.List; import java.util.Map; @Component @Validated public class Person { @Value("${person.name}") private String name; @Value("${person.sex}") private Character sex; @Value("${person.age}") private Integer age; @Value("${person.birthday}") private Date birthday; private Map<String, Integer> maps; private List<String> lists; private Dog dog; public String getName() { return name; } public void setName(String name) { this.name = name; } public Character getSex() { return sex; } public void setSex(Character sex) { this.sex = sex; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } public Map<String, Integer> getMaps() { return maps; } public void setMaps(Map<String, Integer> maps) { this.maps = maps; } public List<String> getLists() { return lists; } public void setLists(List<String> lists) { this.lists = lists; } public Dog getDog() { return dog; } public void setDog(Dog dog) { this.dog = dog; } @Override public String toString() { return "Person{" + "name='" + name + '\'' + ", sex=" + sex + ", age=" + age + ", birthday=" + birthday + ", maps=" + maps + ", lists=" + lists + ", dog=" + dog + '}'; } }
创建Dog类
package com.example.springbootdaily.model; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import org.springframework.validation.annotation.Validated; @Component @Validated public class Dog { @Value("${person.dog.name}") private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "Dog{" + "name='" + name + '\'' + '}'; } }
写一个测试类
import com.example.springbootdaily.model.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; @RunWith(SpringRunner.class) @SpringBootTest public class SpringTest { @Autowired Person person; @Test public void print(){ System.out.println(person); } }
运行结果:
Person{name='岳轩子', sex=雄, age=18, birthday=Sun Mar 03 00:00:00 CST 2002, maps=null, lists=null, dog=null}
2.2 @ConfigurationProperties的用法
创建Person2.java
package com.example.springbootdaily.model; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; import org.springframework.validation.annotation.Validated; import java.util.Date; import java.util.List; import java.util.Map; @Component @ConfigurationProperties(prefix = "person") @Validated public class Person2 { private String name; private Character sex; private Integer age; private Date birthday; private Map<String, Integer> maps; private List<String> lists; private Dog dog; public String getName() { return name; } public void setName(String name) { this.name = name; } public Character getSex() { return sex; } public void setSex(Character sex) { this.sex = sex; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } public Map<String, Integer> getMaps() { return maps; } public void setMaps(Map<String, Integer> maps) { this.maps = maps; } public List<String> getLists() { return lists; } public void setLists(List<String> lists) { this.lists = lists; } public Dog getDog() { return dog; } public void setDog(Dog dog) { this.dog = dog; } @Override public String toString() { return "Person{" + "name='" + name + '\'' + ", sex=" + sex + ", age=" + age + ", birthday=" + birthday + ", maps=" + maps + ", lists=" + lists + ", dog=" + dog + '}'; } }
Dog类
package com.example.springbootdaily.model; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import org.springframework.validation.annotation.Validated; @Component @Validated public class Dog { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "Dog{" + "name='" + name + '\'' + '}'; } }
写测试类
@Test public void print3(){ System.out.println(person2); }
运行结果:
Person{name='岳轩子', sex=雄, age=18, birthday=Sun Mar 03 00:00:00 CST 2002, maps={k1=20, k2=21}, lists=[小黄, 小黑], dog=Dog{name='旺财'}}
3. 区别
3.1 松散绑定
@ConfigurationProperties 的松散绑定(relaxed binding)是 Spring Boot 提供的一个特性,它允许你在配置文件中使用不同的命名风格(如驼峰命名、短横线分隔等),而 Spring Boot 能够自动地将其映射到 Java Bean 的属性上。这种特性使得配置文件的编写更加灵活,同时也使得 Java Bean 的属性命名更加符合 Java 的命名习惯。
松散绑定的工作原理:
当你使用 @ConfigurationProperties 注解来绑定配置文件中的属性时,Spring Boot 会尝试根据以下规则来匹配属性名:
- 驼峰命名与短横线分隔的互转:如果你的 Java Bean 属性使用驼峰命名(如 myProperty),那么你可以在配置文件中使用短横线分隔的形式(如 my-property)来设置这个属性的值。Spring Boot 会自动地将这两种命名风格进行转换。
- 忽略大小写:在松散绑定中,大小写通常会被忽略,但请注意,这取决于你使用的配置文件格式(如 YAML 是大小写敏感的,而 properties 文件则不是)。然而,即使对于大小写敏感的文件格式,Spring Boot 也会尝试以智能的方式匹配属性名。
- 环境变量:对于环境变量,松散绑定的规则也适用。通常,环境变量名使用大写字母和下划线(如 MY_PROPERTY),而 Java Bean 属性则使用驼峰命名。Spring Boot 能够处理这种差异。
例子
application.yml
这里的name中间加了一个线
person: na-me : 岳轩子 sex : 雄 age : 18 birthday : 2002/2/31 maps : { k1 : 20 , k2 : 21} lists : [小黄 , 小黑] dog: name : 旺财
仍然可以获取
运行结果:
Person{name='岳轩子',
3.2 SpEL
SpEL(Spring Expression Language)是 Spring 框架中的一个功能强大的表达式语言,它支持在运行时查询和操作对象图。SpEL 是一种类似于 JSP EL(JavaServer Pages Expression Language)但功能更强大的表达式语言,它用于在运行时查询和操作数据。
主要用途
Bean 属性的动态访问:在 Spring 配置文件中,你可以使用 SpEL 来动态地访问和设置 Bean 的属性。
注解中的属性值:在 Spring 的注解中,你也可以使用 SpEL 来设置注解的属性值。
XML 配置中的属性值:在 Spring 的 XML 配置文件中,可以通过 标签的 value 或 ref 属性结合 SpEL 来设置属性值。
@Value 注解:在 Java 代码中,可以使用 @Value 注解结合 SpEL 来注入配置值或计算结果。
特点
功能强大:支持基本运算、关系运算、逻辑运算、正则表达式匹配、集合操作等。
易于使用:语法简洁,易于学习和使用。
集成性好:与 Spring 框架紧密结合,可以在 Spring 的各种场景中使用。
例子
运行结果
3.3 JSP303数据校验
先导入依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId> </dependency>
这里是@Value,不支持
@Email @Value("${person.name}") private String name;
如果不是email的话,会报错
3.4 复杂类型封装
前面已经使用了,@Value不能封装map,list和对象类型
但是@ConfigurationProperties可以