Spring Boot2.x类型安全属性配置详解

简介: Spring Boot2.x类型安全属性配置详解

image.png在Spring中使用@Value可以对单个属性进行注入配置,但如果有很多配置属性或者配置属性本身拥有层级结构时,Spring Boot提供了基于类型安全的配置方式。本文系统的带大家了解一下基于类型安全的属性配置。

@ConfigurationProperties

通过@ConfigurationProperties将properties属性和一个Bean及其属性关联,从而实现类型安全配置。

就像上面说的,如果在实践的过程中如果有很多配置,通过@Value逐一配置不仅麻烦,还不太符合面向对象的编程思想。根据不同情况,可适当的将对应的配置文件根据业务进行分组,集中管理。此时,基于类型安全的属性配置便发挥了作用。

@ConfigurationProperties加载properties文件内的配置,通过prefix属性指定配置文件中定义的properties配置的统一前缀。

@ConfigurationProperties(prefix = "remote"})

如果对应配置文件不是通过SpringBoot默认加载,Spring Boot1.5之前可通过locations指定properties文的位置,如下:

@ConfigurationProperties(prefix = "remote",locations={"classpath:remote.properties"})

在随后版本逐渐废弃,原因很简单,Spring Boot认为将一个配置类绑定到一个配置文件不太合适。替代方案可以使用@PropertySource来指定自定义的资源目录。

示例代码

下面以具体的实例来演示一下如何使用@ConfigurationProperties。

remote.properties配置文件中配置内容如下:

remote.address= www.choupangxia.com
remote.port= 8080

对应实体类如下:

@Component
@PropertySource({"classpath:remote.properties"})
@ConfigurationProperties(prefix = "remote")
public class RemoteConfig {
/**
* 远程服务地址
*/
private String address;
/**
* 远程服务端口
*/
private int port;
// getter/stetter方法
}

对应RemoteConfig的Bean的使用:













@RestControllerpublic class ConfigurationController {
  @Resource  private RemoteConfig remoteConfig;    @GetMapping  public void getInfo() {    System.out.println("地址:" + remoteConfig.getAddress());    System.out.println("端口:" + remoteConfig.getPort());  }}

单元测试方法内容:

@SpringBootTest
@AutoConfigureMockMvc
class ConfigurationControllerTest {
    @Autowired
    private MockMvc mockMvc;
    @Test
    void getInfo() throws Exception {
        mockMvc.perform(MockMvcRequestBuilders.get("/"));
    }
}

执行,单元测试,日志打印如下:

地址:www.choupangxia.com
端口:8080

说明配置文件中的配置已经完成注入。

通过上述配置为RemoteConfig创建了一个常规的bean,不过Spring Boot建议@ConfigurationProperties只用来处理environment(只用于注入配置,系统环境之类的),不要注入上下文中的其他beans。

第三方配置

@ConfigurationProperties不仅可以注解在类上,也可以注解在public @Bean方法上,当需要为不受控的第三方组件绑定属性时,该方法将非常有用。

配置文件中的属性定义没有区别,注解具体使用如下:

@Configuration
public class MyConfig {
    @Bean
    @ConfigurationProperties(prefix = "user")
    public User user() {
        return new User();
    }
}

松散的绑定约束

Spring Boot将Environment属性绑定到@ConfigurationProperties Bean时会使用一些宽松的规则,所以Environment属性名和Bean属性名不需要精确匹配。

比如在对象User中有一个firstName属性,那么在配置文件中对应如下配置项均会匹配:

user.firstName // 标准驼峰命名语法
user.first-name // 短横线隔开表示,推荐用于.properties和.yml文件中
user.first_name // 下划线表示,用于.properties和.yml文件的可选格式
USER_FIRST_NAME // 大写形式,推荐用于系统环境变量

@ConfigurationProperties校验

当类上标注了@Validated注解,Spring Boot会尝试校验@ConfigurationProperties注解的类。可以在配置类中直接使用JSR-303 javax.validation约束标注。使用之前确保在类路径中存在适用的JSR-303实现:











@Component@PropertySource({"classpath:remote.properties"})@ConfigurationProperties(prefix = "remote")@Validatedpublic class RemoteConfig {
  @NotNull  private String phone;  // getter/setter}

自定义yml文件支持

上面我们提到如果配置文件未配置在默认的application文件内,则需要使用@PropertySource进行指定加载。但如果此时如果你使用的是yml格式的文件,会发现使用@PropertySource无法加载对应的文件。这是因为默认情况下@PropertySource并不支持yml文件的解析。

因此,如果在项目中使用的是yml格式的自定义配置文件,可自定义PropertySourceFactory来进行支持。

首先创建自定义YamlPropertyLoaderFactory:

























public class YamlPropertyLoaderFactory extends DefaultPropertySourceFactory {
  @Override  public PropertySource<?> createPropertySource(@Nullable String name, EncodedResource resource) throws IOException {    Properties propertiesFromYaml = loadYamlIntoProperties(resource);    String sourceName = name != null ? name : resource.getResource().getFilename();    return new PropertiesPropertySource(sourceName, propertiesFromYaml);  }    private Properties loadYamlIntoProperties(EncodedResource resource) throws FileNotFoundException {    try {        YamlPropertiesFactoryBean factory = new YamlPropertiesFactoryBean();        factory.setResources(resource.getResource());        factory.afterPropertiesSet();        return factory.getObject();      } catch (IllegalStateException e) {        Throwable cause = e.getCause();        if (cause instanceof FileNotFoundException) {          throw (FileNotFoundException) e.getCause();        }        throw e;    }  }}

使用@PropertySource将其factory属性指定上面自定义的YamlPropertyLoaderFactory即可正常加载。

@PropertySource(value = "classpath:remote.yml",factory = YamlPropertyLoaderFactory.class)

小结

关于SpringBoot类型安全属性配置就讲解这么多,其中Bean中嵌套Bean,或Bean中嵌套Bean的校验等均可在此基础上进行拓展,基本使用方法都是一致的。


目录
相关文章
|
4天前
|
Java 开发者 微服务
手写模拟Spring Boot自动配置功能
【11月更文挑战第19天】随着微服务架构的兴起,Spring Boot作为一种快速开发框架,因其简化了Spring应用的初始搭建和开发过程,受到了广大开发者的青睐。自动配置作为Spring Boot的核心特性之一,大大减少了手动配置的工作量,提高了开发效率。
20 0
|
29天前
|
Java API 数据库
Spring Boot框架因其简洁的配置、快速的启动特性及丰富的功能集而备受开发者青睐
本文通过在线图书管理系统案例,详细介绍如何使用Spring Boot构建RESTful API。从项目基础环境搭建、实体类与数据访问层定义,到业务逻辑实现和控制器编写,逐步展示了Spring Boot的简洁配置和强大功能。最后,通过Postman测试API,并介绍了如何添加安全性和异常处理,确保API的稳定性和安全性。
35 0
|
22天前
|
Java API Spring
在 Spring 配置文件中配置 Filter 的步骤
【10月更文挑战第21天】在 Spring 配置文件中配置 Filter 是实现请求过滤的重要手段。通过合理的配置,可以灵活地对请求进行处理,满足各种应用需求。还可以根据具体的项目要求和实际情况,进一步深入研究和优化 Filter 的配置,以提高应用的性能和安全性。
|
9天前
|
缓存 IDE Java
SpringBoot入门(7)- 配置热部署devtools工具
SpringBoot入门(7)- 配置热部署devtools工具
20 2
 SpringBoot入门(7)- 配置热部署devtools工具
|
7天前
|
Java 数据库连接
SpringBoot配置多数据源实战
第四届光学与机器视觉国际学术会议(ICOMV 2025) 2025 4th International Conference on Optics and Machine Vision
34 8
|
5天前
|
Java 数据库连接 数据库
springboot启动配置文件-bootstrap.yml常用基本配置
以上是一些常用的基本配置项,在实际应用中可能会根据需求有所变化。通过合理配置 `bootstrap.yml`文件,可以确保应用程序在启动阶段加载正确的配置,并顺利启动运行。
12 2
|
9天前
|
分布式计算 关系型数据库 MySQL
SpringBoot项目中mysql字段映射使用JSONObject和JSONArray类型
SpringBoot项目中mysql字段映射使用JSONObject和JSONArray类型 图像处理 光通信 分布式计算 算法语言 信息技术 计算机应用
31 8
|
14天前
|
Java Spring
[Spring]aop的配置与使用
本文介绍了AOP(面向切面编程)的基本概念和核心思想。AOP是Spring框架的核心功能之一,通过动态代理在不修改原代码的情况下注入新功能。文章详细解释了连接点、切入点、通知、切面等关键概念,并列举了前置通知、后置通知、最终通知、异常通知和环绕通知五种通知类型。
27 1
|
16天前
|
Java Spring 容器
SpringBoot读取配置文件的6种方式,包括:通过Environment、@PropertySource、@ConfigurationProperties、@Value读取配置信息
SpringBoot读取配置文件的6种方式,包括:通过Environment、@PropertySource、@ConfigurationProperties、@Value读取配置信息
43 3
|
27天前
|
druid Java Maven