一、@Value获取值和@ConfigurationProperties获取值比较

如果某个业务逻辑中只需要获取配置文件中的某项值时使用@Value;
如果专门编写了一个javaBean和配置文件进行映射,使用@ConfigurationProperties

@ConfigurationProperties

@Value

功能

批量注入配置文件中的属性

一个一个指定

优先级(高优先级覆盖低优先级,配置互补)



松散绑定(松散语法:person.lastName == person.last-name)

支持

不支持

JSR303数据校验(@Validated)

支持

不支持

复杂类型封装(对象、List、Set、Map,等)

支持

不支持

配置文件格式.yml和.properties

支持

支持

二、配置文件.properties和.yml优先级

在application.properties中添加person属性值,当application.properties和application.yml中同时定义person属性值时,同一目录下.properties配置文件的优先级高于.yml配置文件,高优先级会覆盖低优先级的属性值,并且配置互补。

person.last-name=李四
person.age=20
person.boss=false
person.birth=201901/01/02
person.maps.k1=v1
person.maps.k2=v2
person.maps.k3=v3
person.lists=a,b,c
person.dog.name=小花狗
person.dog.age=3

三、编码问题

使用.properties配置文件中的属性值时,打印在控制台的结果中文乱码。

解决方法:打开Settings,File > Settings

Springboot 注入service springboot 注入map配置文件 @value_配置文件


修改后application.properties配置文件中的中文会乱码,重新输入再次测试。

三、@Value

@Value的赋值方式和Spring IOC中使用set注入方式相同(什么是set注入) 使用set注入,值可以是:字面量、${key} 从环境变量或者配置中获取值、#{SpEL} EL表达式

<bean class="cn.springboottest.springboot.bean.Person" >
        <property key="lastName" value="字面量/${key}从环境变量,配置文件中获取值/#{SpEL}"></property>
    </bean>

测试,先将@ConfigurationProperties(prefix = “person”)注释掉

package cn.springboottest.springboot.bean;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 将配置文件中配置的每一个属性值,映射到这个组件中
 * @ConfigurationProperties: 告诉Spring Boot将本类中的所有属性和配置文件中相关的配置进行绑定
 * prefix ="person":配置文件中哪个下面的所有属性进行一一映射
 *
 * 只有这个组件是容器中的组件,才能使用容器提供的@ConfigurationProperties功能
 *
 * @ConfigurationProperties(prefix = "person")默认从全局配置文件中获取值;
 *
 *
 */
@Component
//@ConfigurationProperties(prefix = "person")
public class Person {
    /*
    <bean class="cn.springboottest.springboot.bean.Person" >
        <property key="lastName" value="字面量/${key}从环境变量,配置文件中获取值/#{SpEL}"></property>
    </bean>
     */
    @Value("${person.last-name}")
    private String lastName;
    @Value("#{11*5}")
    private Integer age;
    @Value("true")
    private Boolean boss;
    private Date birth;

    private Map<String, Object> maps;
    private List<Object> lists;
    private Dog dog;

    @Override
    public String toString() {
        return "Person{" +
                "lastName='" + lastName + '\'' +
                ", age=" + age +
                ", boss=" + boss +
                ", birth=" + birth +
                ", maps=" + maps +
                ", lists=" + lists +
                ", dog=" + dog +
                '}';
    }

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

测试结果:未赋值的的属性值为null

Person{lastName='李四', age=55, boss=true, birth=null, maps=null, lists=null, dog=null}

放开@ConfigurationProperties(prefix=“person”)注解配置,@Value和@ConfigurationProperties同时存在,@ConfigurationProperties优先级高于@Value,高优先级覆盖低优先级,互补配置

四、@Value使用案例

  1. 创建Controller
package cn.springboottest.springboot.controller;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloController {

    @Value("${person.last-name}")
    private String name;

    @RequestMapping("/sayHello")
    public String sayHello(){
        return "Hello "+ name;
    }
}
  1. 测试结果

五、@Validated

配置文件注入值数据校验,在类上增加注解配置@Validated
在属性值上增加@Email,代表该属性值必须是email格式,否则在编译启动的过程中会抛错。
@Value 对 @Validated + @Email 不生效
示例:

package cn.springboottest.springboot.bean;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
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;

/**
 * 将配置文件中配置的每一个属性值,映射到这个组件中
 * @ConfigurationProperties: 告诉Spring Boot将本类中的所有属性和配置文件中相关的配置进行绑定
 * prefix ="person":配置文件中哪个下面的所有属性进行一一映射
 *
 * 只有这个组件是容器中的组件,才能使用容器提供的@ConfigurationProperties功能
 *
 * @ConfigurationProperties(prefix = "person")默认从全局配置文件中获取值;
 *
 *
 */
@Component
@ConfigurationProperties(prefix = "person")
@Validated
public class Person {
    /*
    <bean class="cn.springboottest.springboot.bean.Person" >
        <property key="lastName" value="字面量/${key}从环境变量,配置文件中获取值/#{SpEL}"></property>
    </bean>
     */
    //@Value("${person.last-name}")
    @Email
    private String lastName;
    //@Value("#{11*5}")
    private Integer age;
    //@Value("true")
    private Boolean boss;
    private Date birth;

    private Map<String, Object> maps;
    private List<Object> lists;
    private Dog dog;

    @Override
    public String toString() {
        return "Person{" +
                "lastName='" + lastName + '\'' +
                ", age=" + age +
                ", boss=" + boss +
                ", birth=" + birth +
                ", maps=" + maps +
                ", lists=" + lists +
                ", dog=" + dog +
                '}';
    }

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

测试结果:

Caused by: org.springframework.boot.context.properties.bind.validation.BindValidationException: Binding validation errors on person
   - Field error in object 'person' on field 'lastName': rejected value [李四]; codes [Email.person.lastName,Email.lastName,Email.java.lang.String,Email]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [person.lastName,lastName]; arguments []; default message [lastName],[Ljavax.validation.constraints.Pattern$Flag;@1d572e62,.*]; default message [不是一个合法的电子邮件地址]; origin class path resource [application.properties]:1:18
	at org.springframework.boot.context.properties.bind.validation.ValidationBindHandler.getBindValidationException(ValidationBindHandler.java:121)
	at org.springframework.boot.context.properties.bind.validation.ValidationBindHandler.validateAndPush(ValidationBindHandler.java:112)
	at org.springframework.boot.context.properties.bind.validation.ValidationBindHandler.validate(ValidationBindHandler.java:90)
	at org.springframework.boot.context.properties.bind.validation.ValidationBindHandler.onFinish(ValidationBindHandler.java:82)
	at org.springframework.boot.context.properties.bind.Binder.handleBindResult(Binder.java:228)
	at org.springframework.boot.context.properties.bind.Binder.bind(Binder.java:215)
	... 46 more