springboot版本2.5.5下@ConfigurationProperties的源码

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Indexed
public @interface ConfigurationProperties {
    @AliasFor("prefix")
    String value() default "";

    @AliasFor("value")
    String prefix() default "";

    boolean ignoreInvalidFields() default false;

    boolean ignoreUnknownFields() default true;
}

1.@ConfigurationProperties的作用

@ConfigurationProperties一次性读取配置文件并映射到javabean
在做项目的时候需要使用代码实现读取properties/yml的文件中的配置,springboot提供了@ConfigurationProperties注解来完成这个工作

2.@ConfigurationProperties的参数解释

  • 参数一:value:
    前缀,用于识别properties/yml文件里需要映射的属性的统一前缀
  • 参数二:prefix:
    前缀,用于识别properties/yml文件里需要映射的属性的统一前缀
  • 参数三:ignoreInvalidFields:false
    是否忽略非法值,比如将一个字符串 “foo” 赋值给 bool 值,不忽略的话会报启动异常。
  • 参数四:ignoreUnknownFields:true
    对于多余的配置是否会报异常。例如:当配置文件中有一个或多个属性未绑定到实体类时或属性名字出错或已被删除了,这时候对于实体类,properties里的属性是未知的。这种情况我们希望程序启动失败,这时候就将此参数设置为false即可

3.@ConfigurationProperties的使用

配置文件

service:
  global: global
  name: test
  enabled: true
  remoteAddress: 127.0.0.1
  securities:
    - username: csx1
      password: password1
    - username: csx2
      password: password2

3.1.配置文件与javabean映射/绑定

javabean
注意点:

  • JavaBean要映射的属性需要有public的setter方法 比如: @Data
  • JavaBean需要交给容器管理 比如:@Component
  • JavaBean中静态成员变量的不支持映射/绑定
@Data
@ConfigurationProperties("service")
@Component
public class MyProperties {
    /**
     * 静态属性
     */
    private static String global;

    /**
     * 简单类型
     */
    private String name;
    /**
     * 简单类型 映射
     */
    private boolean enabled;

    /**
     * 引用类型 映射
     */
    private InetAddress remoteAddress;

    /**
     * 集合类型映射
     */
    private List<Security> securities;

    @Data
    public static class Security {
        private String username;
        private String password;
    }
}

测试

/**
 * 测试@ConfigurationProperties
 */
@RestController
public class TestConfigController {
    @Autowired
    private MyProperties myProperties;

    @RequestMapping("/testConfig")
    public MyProperties testConfig() {
        return myProperties;
    }
}

测试返回的json

{
  "name": "test",
  "enabled": true,
  "remoteAddress": "127.0.0.1",
  "securities": [
    {
      "username": "csx1",
      "password": "password1"
    },
    {
      "username": "csx2",
      "password": "password2"
    }
  ]
}

3.2 @ConstructorBinding构造函数映射/绑定

注意点:

  • JavaBean 依然需要增加注解@ConfigurationProperties
  • JavaBean 需要提供 getter 方法。
  • 使用构造函数绑定的方式,只能 @EnableConfigurationProperties 或者 @ConfigurationPropertiesScan 的方式注入 Bean。不能使用 @Component、@Bean 或者 @Import 的方式。
  • 使用构造函数绑定的方式,只有被注解的构造器的参数被映射,其他属性不会被映射
@Getter
@ConfigurationProperties("service")
//@Data
//@Component
public class MyProperties {
    /**
     * 静态属性
     */
    private static String global;

    /**
     * 宽松绑定原则
     */
    private String contextPath;

    /**
     * 简单类型
     */
    private String name;
    /**
     * 简单类型 映射
     */
    private boolean enabled;

    /**
     * 引用类型 映射
     */
    private InetAddress remoteAddress;

    /**
     * 集合类型映射
     */
    private List<Security> securities;

    @Data
    public static class Security {
        private String username;
        private String password;
    }

    @ConstructorBinding
    MyProperties(boolean enabled, InetAddress remoteAddress, List<Security> securities) {
        this.enabled = enabled;
        this.remoteAddress = remoteAddress;
        this.securities = securities;
    }
}

测试返回

{
  "contextPath": null,
  "name": null,
  "enabled": true,
  "remoteAddress": "127.0.0.1",
  "securities": [
    {
      "username": "csx1",
      "password": "password1"
    },
    {
      "username": "csx2",
      "password": "password2"
    }
  ]
}

4.@ConfigurationProperties支持宽松绑定原则(Relaxed Binding)

所谓的宽松绑定原则是指:并不是 JavaBean 中的属性必须要和配置文件中的一致才能绑定数据,context-path 也能绑定到 contextPath 属性上

5.保证 MyProperties 能被 Spring 扫到的几种方式

5.1使用注解@Component

@Data
@ConfigurationProperties("service")
@Component
public class MyProperties {
}

5.2使用@Bean注解

@Data
@ConfigurationProperties("service")
public class MyProperties {
}

@Configuration
public class ServiceConfig {
    @Bean
    public MyProperties getMyProperties() {
        return new MyProperties();
    }
}

5.3使用@EnableConfigurationProperties注解

@Data
@ConfigurationProperties("service")
public class MyProperties {
}
@Configuration
@EnableConfigurationProperties(MyProperties.class)
public class ServiceConfig {
}

5.4使用@ConfigurationPropertiesScan(“com.example.demo.bean”)注解指定MyProperties所在的包路径

@SpringBootApplication
@Configuration
@ConfigurationPropertiesScan("com.example.demo.bean")
public class DemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

6.其他

  • @DefaultValue 可以指定默认值
  • @ConfigurationPropertie和 @Value 对比
    @Value 是 Spring Framework 中的注解
    @ConfigurationProperties 是在 Spring Boot 中引入的。
Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐