yml通过@@ConfigurationProperties和@value方式来装载配置信息

一、绑定值的两种方式:

  • @ConfigurationProperties
  • @Value
  1. 优先级:如果两者混用@ConfigurationProperties的优先级比@value的优先级高,但是二者可以互补;
  2. @ConfigurationProperties的数据来源于application.properties和application.yml文件;

         @Value的数据是写死的,来源于配置文件无关;

     3. @ConfigurationProperties支持批量加载 / 注入,@Value单个注入;

     4. 松散语法:(username-->user_name(驼峰-->_的形式))

         @ConfigurationProperties支持;@Value不支持;

      5. SpEL:

         @ConfigurationProperties不支持,@value支持;

      6. JSR303数据校验:

          @ConfigurationProperties支持;@Value不支持;

      7. 注入复杂类型

           @ConfigurationProperties支持,@Value不支持;

二、@PropertySource:

  1. 默认会加载application.yml和applicaiton.properties文件中的数据,如果数据不在这两个文件中,需要通过该注解进行指定:@PropertySource("classpath:user.properties");
  2. @PropertySource注解只能加载properties文件不能加载yml等文件 (只能加载application.yml文件,不能加载其他yml文件);
  3. 加载指定的属性文件(*.properties)到Spring的容器中,可以使用@PropertySource配合@Value和@ConfigurationProperties;
  •  @PropertySource 和 @Value 组合使用,可以将自定义属性文件中的属性变量值注入到当前类的使用@Value注解的成员变量中。
  •  @PropertySource 和 @ConfigurationProperties 组合使用,可以将属性文件与一个Java类绑定,将属性文件中的变量值注入到该Java类的成员变量中。

源码

package org.springframework.context.annotation;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.core.io.support.PropertySourceFactory;

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Repeatable(PropertySources.class)
public @interface PropertySource {
    String name() default "";

    String[] value();

    boolean ignoreResourceNotFound() default false;

    String encoding() default "";

    Class<? extends PropertySourceFactory> factory() default PropertySourceFactory.class;
}

使用实例

在项目跟路径下创建 user.properties

properties/yml通过使用@ConfigurationProperties来装载配置信息-LMLPHP

属性文件 user.properties

user.name=jacklin
user.age=22
user.job=IT行业
[email protected]

演示实例一:@PropertySource 和 @Value

/**
 * @Author 林必昭
 * @Date 2019/11/28 16:28
 * @descr
 */

@Component
@PropertySource(value = "classpath:/user.properties")
public class ReadUserByPropertySourceValue {

    @Value("${user.name}")
    private String name;

    @Value("${user.age}")
    private Integer age;

    @Value("${user.job}")
    private String job;

    @Value("${user.email}")
    private String email;

    @Override
    public String toString() {
        return "ReadUserByPropertySourceValue{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", job='" + job + '\'' +
                ", email='" + email + '\'' +
                '}';
    }
}

演示实例二:@PropertySource 和 @ConfigurationProperties

@Component
@PropertySource(value = {"classpath:/user.properties"})
@ConfigurationProperties(prefix = "user")
public class ReadUserByPropertySourceAndConfigurationProperties {

    private String name;
    private Integer age;
    private String job;
    private String email;

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

    public String getJob() { return job; }

    public void setJob(String job) { this.job = job; }

    public String getEmail() { return email; }

    public void setEmail(String email) { this.email = email;}

    @Override
    public String toString() {
        return "ReadUserByPropertySourceAndConfigurationProperties{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", job='" + job + '\'' +
                ", email='" + email + '\'' +
                '}';
    }
}

测试示例

@Slf4j
@SpringBootApplication
public class SpringPropertiesInjectionDemoApplication implements CommandLineRunner {

    @Autowired
    private ReadUserByPropertySourceValue readUserByPropertySourceValue;

    @Autowired
    private ReadUserByPropertySourceAndConfigurationProperties readUserByPropertySourceAndConfigurationProperties;


    public static void main(String[] args) {
        SpringApplication.run(SpringPropertiesInjectionDemoApplication.class, args);
    }

    @Override
    public void run(String... args) throws Exception {
        log.info(readUserByPropertySourceValue.toString());
        log.info(readUserByPropertySourceAndConfigurationProperties.toString());
    }
}

启动项目观察控制台日志打印输出:

properties/yml通过使用@ConfigurationProperties来装载配置信息-LMLPHP

哎,我们观察到的我们配置文件设置的name明明为jacklin,这里为什么输出Administrator呢,原因是@PropertySource除了可以注入properties文件的设置的值,还可以注入环境变量的值,比如:

@Value("${user.name}")
private String userName;

这个${user.name} 注入的是环境变量中的值

Administrator

创建user1.properties配置文件,将name修改为username

user1.username=jacklin
user1.age=30
user1.job=计算机网络专业
[email protected]

ReadUserByPropertySourceAndConfigurationProperties修改如下:

@Component
@PropertySource(value = {"classpath:/user1.properties"})
@ConfigurationProperties(prefix = "user1")
public class ReadUserByPropertySourceAndConfigurationProperties {

    private String username;
    private Integer age;
    private String job;
    private String email;
    public String getName() {
        return name;
    }
}

运行结果:

properties/yml通过使用@ConfigurationProperties来装载配置信息-LMLPHP

输出结果:

2019-11-28 18:24:38.691  INFO 24080 --- [           main] SpringPropertiesInjectionDemoApplication : ReadUserByPropertySourceValue{username='林必昭', age=22, job='IT行业', email='[email protected]'}
2019-11-28 18:24:38.691  INFO 24080 --- [           main] SpringPropertiesInjectionDemoApplication : ReadUserByPropertySourceAndConfigurationProperties{username='jacklin', age=30, job='计算机网络专业', email='[email protected]'}
  • 发现我们设置的属性都注入成功了!!

加载顺序:application.properties/application.yml > xxx.properties/application-xxx.xml,当application.properties/application.yml存在的时候会先去加载。

11-28 21:44