注解 @ConfigureProperties、松散绑定、数据校验、@Value 绑定

2023/02/21 SpringBoot 共 4676 字,约 14 分钟
技术的搬运工

SpringBoot中通过注解绑定yml配置文件中的数据、实体类中字段的数据校验。

@ConfigureProperties

@ConfigurationProperties 主要作用就是将 prefix 属性指定的前缀配置项的值绑定到这个 JavaBean 上 ,
通过指定的前缀,来绑定配置文件中的配置。

标注在类上

需要添加如下依赖:
否则报错:SpringBoot中使用@ConfigurationProperties提示:Configuration Annotation Processor not found in classpath
官方解决办法

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-configuration-processor</artifactId>
    <optional>true</optional>
</dependency>
/**
 * 阿里云配置
 */
@Configuration  // 配置注解 或者使用 @Component 注解
@Data  // 使用该注解需要导入 lombok 依赖
@ConfigurationProperties(prefix = "aliyun")
public class AliyunConfig {

    // 是否启用rabbitmq
    private Boolean rabbitmqEnabled = false;  // 字段给出初始值

    // access-key
    private String accessKey = null;

    // access-secret
    private String accessSecret = null;

    // resource-id
    private Long resourceId = 0L;

    // 开放搜索Host
    private String openSearchHost = "";

    // 日志Endpoint
    private String logEndpoint = "";

    // 日志项目名
    private String logProject = "";

    // 商品同步log-store
    private String logStoreProductSync = "";

}

application.yml 配置文件对应的内容(这里需要注意父工程和子工程中配置文件的激活方法):

aliyun:
  rabbitmq-enabled: false
  access-key: LTAb4FtapvT8KCz5yt3JjbTM
  access-secret: 3ld4ZX35dcc3cx64KOUmGGfv48zVVa
  resource-id: 1009200965678565
  open-search-host: http://opensearch-cn-shenzhen.aliyuncs.com
  log-endpoint: cn-shenzhen.log.aliyuncs.com
  log-project: s2b-project
  log-store-product-sync: product-sync-log-dev

接下来通过控制器方法来返回这个对象,查看数据是否绑定:

@RestController
@RequestMapping("/test") // 接口前缀
public class AdminTestController {

    @Autowired
    private AliyunConfig aliyunConfig;

    @GetMapping("/aliyunData")
    public void getAliyunConfigData() {
        System.out.println(aliyunConfig);
        System.out.println("啊哈哈哈哈哈哈哈");
    }
}

查看输出:

AliyunConfig(rabbitmqEnabled=false, accessKey=LTAb4FtapvT8KCz5yt3JjbTM, accessSecret=3ld4ZX35dcc3cx64KOUmGGfv48zVVa, resourceId=1009200965678565, openSearchHost=http://opensearch-cn-shenzhen.aliyuncs.com, logEndpoint=cn-shenzhen.log.aliyuncs.com, logProject=s2b-project, logStoreProductSync=product-sync-log-dev, logStoreMqConsumerException=, logStorePushProductStatusChange=)
啊哈哈哈哈哈哈哈

松散绑定

我们在使用 @ConfigurationProperties 注解的时候,@ConfigurationProperties(prefix = “userinfo”),这里给prefix的属性值与yml文件中的属性名称不一致,但是依旧绑定成功了!原因是什么呢?
这就需要提到Spring的松散绑定属性规则。因此使用以下方式书写都能与类的属性名称匹配。

userInfo:
    userId: 1001
    name: luxi

需要注意的是,prefix的属性值必须全部为小写,如下所示,就会报错:前缀必须是规范形式。

@Data
@Component
@ConfigurationProperties(prefix = "userInfo")   // prefix的属性值必须全部为小写,所以这里报错:Prefix must be in canonical form
public class UserInfo {
    // 
}

数据校验

Spring Boot中有很多配置文件,配置文件中我们可以自定义一些对应的属性值。那么这些属性值是否合法呢?我们如何来校验?在Java中有一种 JSR303规范,我们可以针对一些对应的数值来进行校验。按照规范来进行书写,如果不符合要求就说明校验失败,反之,则成功!

SpringBoot也给出了强大的数据校验功能,可以有效的避免此类问题的发生。在JAVA EE的JSR303规范中给出了具体的数据校验标准,开发者可以根据自己的需要选择对应的校验框架,此处使用Hibernate提供的校验框架来作为实现进行数据校验。

导入 验证依赖 和 校验实现依赖

<dependency>
    <groupId>javax.validation</groupId>
    <artifactId>validation-api</artifactId>
    <version>2.0.1.Final</version>
</dependency>

<dependency>
    <groupId>org.hibernate.validator</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>6.0.15.Final</version>
</dependency>

添加注解 @Validated 给属性添加验证规则:

@Data
@Component
@ConfigurationProperties(prefix = "userinfo")
@Validated
public class UserInfo {
   
   @Max(value=100, message="userId超出范围")
   @Min(value=0, message="userId不能为0")
   private String userId;
   
   @Size(min=2, max=5, message="name长度在2~5之间")
   private String name;
}

我们先输入不符合规范的数据,来验证数据是否能够校验成功:

userInfo:
    userId: 11
    name: luxiplus

编写一个控制器方法来检验

@RestController
@RequestMapping("/test") // 接口前缀
public class AdminTestController {

    @Autowired
    private UserInfo userInfo;
    
     @GetMapping("/userInfo")
     public void getUserInfoData() {
        System.out.println(userInfo);
        System.out.println("啦啦啦啦啦啦");
     }
}

运行程序,查看控制台,可以看到 name 校验不通过:

Description:

Binding to target org.springframework.boot.context.properties.bind.BindException: Failed to bind properties under 'userinfo' to com.hmf.cresta.admin.controller.UserInfo failed:

    Property: userinfo.name
    Value: luxiplus
    Origin: class path resource [application-admin.yml] - 14:9
    Reason: name长度在2~5之间

当然,这里的校验规则还有许多,@NotNull、@NotEmpty、@Email 等等,可以根据实际情况选择合适的注解。

@Value

通过 @Value 注解,直接绑定 yml 配置文件中的某个配置数据。

application.yml 配置文件对应的内容:

aliyun:
  rabbitmq-enabled: false
  access-key: LTAb4FtapvT8KCz5yt3JjbTM
  access-secret: 3ld4ZX35dcc3cx64KOUmGGfv48zVVa
  resource-id: 1009200965678565
  open-search-host: http://opensearch-cn-shenzhen.aliyuncs.com
  log-endpoint: cn-shenzhen.log.aliyuncs.com
  log-project: s2b-project
  log-store-product-sync: product-sync-log-dev

在需要绑定 yml 配置数据的类中,使用如下代码进行绑定:

@Value("${aliyun.access-key}")  // 绑定 aliyun.access-key 的配置数据,需要和yml配置数据中的字段名完全一致,才能绑定成功
private String accessKey;

编写一个控制器方法来检验:

@RestController
@RequestMapping("/test") // 接口前缀
public class AdminTestController {

    @Value("${aliyun.access-key}")
    private String accessKey;
    
     @GetMapping("/accessKey")
     public void getUserInfoData() {
        System.out.println("accessKey: " + accessKey);
     }
}

运行程序,查看控制台输出内容:

accessKey: LTAb4FtapvT8KCz5yt3JjbTM

文档信息