SpringBoot -- 02 -- @ConfigurationProperties和@PropertySource注解的使用

在 SpringBoot 项目的开发过程中,我们通常会需要读取配置文件中的配置项,并将其封装到一个实体类中。说到读取配置项,我们第一个想到的会是 @Value 注解,但这仅适合用读取少量的配置项,一旦配置项过多,再使用 @Value 注解就会显的很麻烦了,这时候我们就可以使用 @ConfigurationProperties 注解了,它会自动将配置文件中的同名配置项映射为实体类中对应的属性。此外,如果有些配置项我们想单独自定义一个配置文件,这时候可以使用 @PropertySource 注解,它可以与 @ConfigurationProperties 注解一起搭配使用,现在让我们来一起看看它们的具体用法


一、@ConfigurationProperties

@ConfigurationProperties 注解支持松散绑定,所谓松散绑定就是说,在配置文件中使用 first_name、first-name 等连接符时,会自动将其绑定至实体类中对应的驼峰规则的属性,即 firstName

  • application.yml

    test:
      student:
        first_name: Tony
        second_name: Jack
        third_name: Andy
    
  • MyConfiguration.java

    @Component
    @ConfigurationProperties(value = "test")
    public class MyConfiguration {
    
        private Student student;
    
        public Student getStudent() {
            return student;
        }
    
        public void setStudent(Student student) {
            this.student = student;
        }
    
        @Override
        public String toString() {
            return "MyConfiguration{" +
                    "student=" + student +
                    '}';
        }
    }
    
  • Student.java

    public class Student {
    
        private String firstName;
        private String secondName;
        private String thirdName;
    
        public String getFirstName() {
            return firstName;
        }
    
        public void setFirstName(String firstName) {
            this.firstName = firstName;
        }
    
        public String getSecondName() {
            return secondName;
        }
    
        public void setSecondName(String secondName) {
            this.secondName = secondName;
        }
    
        public String getThirdName() {
            return thirdName;
        }
    
        public void setThirdName(String thirdName) {
            this.thirdName = thirdName;
        }
    
        @Override
        public String toString() {
            return "Student{" +
                    "firstName=" + firstName +
                    ", secondName=" + secondName +
                    ", thirdName=" + thirdName +
                    '}';
        }
    }
    
  • Test.java

    @Configuration
    public class Test {
    
        @Autowired
        private MyConfiguration myConfiguration;
    
        @PostConstruct
        private void test() {
            System.out.println(myConfiguration);
        }
    }
    
    // MyConfiguration{student=Student{firstName=Tony, secondName=Jack, thirdName=Andy}}
    

    如上所示,@ConfigurationProperties 注解自动将配置项映射为了实体类中对应的属性,且支持实体类嵌套映射

    @ConfigurationProperties 注解一个有四个属性,如下所示

    • value

      • 作用与 prefix 相同,但是 prefix 与 value 只能同时存在一个,默认为 “”
    • prefix

      • 配置项的前缀,表示映射该前缀下的配置项
    • ignoreInvalidFields

      • 是否忽略非法字段

      • 默认为 false,则当配置项字段类型与实体类字段类型不相同时,程序启动时会抛出异常

      • 如果设为 true,则配置项与实体类仅需要字段名相同即可,而不用关心字段类型,程序可以正常启动

    • ignoreUnknownFields

      • 是否忽略未知字段

      • 默认为 true,则当配置项中存在实体类中不存在的字段时,程序可以正常启动

      • 如果设为 false,则配置项需要与实体类中的字段一一对应,否则程序启动时会抛出异常


二、@PropertySource

@PropertySource 注解主要用于加载指定的配置文件

  • config.properties

    test.student.first_name=Yuki
    test.student.second_name=Tom
    test.student.third_name=Amy
    
  • MyConfiguration.java

    @Component
    @ConfigurationProperties(prefix = "test")
    @PropertySource(value = "classpath:config.properties")
    public class MyConfiguration {
    
        private Student student;
    
        public Student getStudent() {
            return student;
        }
    
        public void setStudent(Student student) {
            this.student = student;
        }
    
        @Override
        public String toString() {
            return "MyConfiguration{" +
                    "student=" + student +
                    '}';
        }
    }
    
  • Student.java

    public class Student {
    
        private String firstName;
        private String secondName;
        private String thirdName;
    
        public String getFirstName() {
            return firstName;
        }
    
        public void setFirstName(String firstName) {
            this.firstName = firstName;
        }
    
        public String getSecondName() {
            return secondName;
        }
    
        public void setSecondName(String secondName) {
            this.secondName = secondName;
        }
    
        public String getThirdName() {
            return thirdName;
        }
    
        public void setThirdName(String thirdName) {
            this.thirdName = thirdName;
        }
    
        @Override
        public String toString() {
            return "Student{" +
                    "firstName=" + firstName +
                    ", secondName=" + secondName +
                    ", thirdName=" + thirdName +
                    '}';
        }
    }
    
  • Test.java

    @Configuration
    public class Test {
    
        @Autowired
        private MyConfiguration myConfiguration;
    
        @PostConstruct
        private void test() {
            System.out.println(myConfiguration);
        }
    }
    
    // MyConfiguration{student=Student{firstName=Yuki, secondName=Tom, thirdName=Amy}}
    

    如上所示,@PropertySource 注解与 @ConfigurationProperties 注解搭配使用,也可以将配置项映射为实体类中对应的属性,且支持实体类嵌套映射

    @PropertySource 注解一个有五个属性,如下所示

    • name

      • 配置文件唯一标识,默认为 “”,由程序自动生成
    • value

      • 配置文件路径,数组类型,可设置多个,没有默认值
    • ignoreResourceNotFound

      • 是否忽略配找不到配置文件异常

      • 默认为 false,则当找不到指定的配置文件时,程序启动时会抛出异常

      • 如果设为 true,则当找不到指定的配置文件时,程序可以正常启动

    • encoding

      • 配置文件编码,默认为 “”;通常情况下我们可以将其设为 “UTF-8”
    • factory

      • 属性源工厂,默认为 PropertySourceFactory.class

PS:以下几点需要注意一下

  • 当主配置文件 (application.yml) 与自定义配置文件 (config.properties) 中存在相同名称的配置项时,主配置文件会覆盖自定义配置文件

  • 使用 @ConfigurationProperties 时,还需要将该配置类注册为 bean 对象,也就是搭配使用了 @Component 注解;如果不使用 @Component 注解,我们还可以使用 @EnableConfigurationProperties 注解,该注解作用于启动类,且需要指定使用了 @ConfigurationProperties 注解的配置类

    • MyConfiguration.java

      @ConfigurationProperties(prefix = "test")
      public class MyConfiguration {
      
          private Student student;
      
          public Student getStudent() {
              return student;
          }
      
          public void setStudent(Student student) {
              this.student = student;
          }
      
          @Override
          public String toString() {
              return "MyConfiguration{" +
                      "student=" + student +
                      '}';
          }
      }
      
    • SpringbootTestApplication.java

      @EnableConfigurationProperties(value = MyConfiguration.class)
      @SpringBootApplication
      public class SpringbootTestApplication  {
      
          public static void main(String[] args) {
              SpringApplication.run(SpringbootTestApplication.class, args);
          }
      }
      

三、参考资料

posted @ 2019-06-04 16:41  GeneXu  阅读(298)  评论(0)    收藏  举报