ConfigurationProperties和EnableConfigurationProperties的区别

总结一下:

  • @ConfigurationProperties 用于指定将要绑定到类上的属性的前缀。
  • @EnableConfigurationProperties 用于告诉 Spring Boot 创建带有 @ConfigurationProperties 注解的类的 bean。
  • 前者只是声明,如果想在spring容器中使用这些属性,则需要使用component注解或者EnableConfigurationProperties去把class属性注册到spring容器中

EnableConfigurationProperties和ConfigurationProperties

假设你在 application.yml 文件中有如下的配置:

1
2
3
4
5
myapp:
server:
url: http://localhost:8080
username: user
password: pass

你想要将这个配置绑定到一个 Java 对象上,你可以使用 @ConfigurationProperties 注解来完成这个任务:

1
2
3
4
5
6
7
8
9
10
11
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

@Component
@ConfigurationProperties(prefix = "myapp.server")
public class ServerProperties {
private String url;
private String username;
private String password;
// getters and setters
}

在这个例子中,@ConfigurationProperties(prefix = "myapp.server") 告诉 Spring Boot 将所有以 myapp.server 开头的属性绑定到这个类的字段上。@Component 注解则告诉 Spring 将这个类视为一个 bean,并在 Spring 上下文中管理它。

现在,你可以在应用的任何地方注入 ServerProperties 并使用它:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class MyController {
private final ServerProperties serverProperties;

@Autowired
public MyController(ServerProperties serverProperties) {
this.serverProperties = serverProperties;
}

@GetMapping("/server")
public String getServerDetails() {
return "URL: " + serverProperties.getUrl() +
", Username: " + serverProperties.getUsername() +
", Password: " + serverProperties.getPassword();
}
}

然而,使用 @EnableConfigurationProperties,有另一种方式可以达到同样的效果。不是给 ServerProperties 打上 @Component 标签,而是在一个 @Configuration 类中使用 @EnableConfigurationProperties

1
2
3
4
5
6
7
8
9
import org.springframework.boot.context.properties.ConfigurationProperties;

@ConfigurationProperties(prefix = "myapp.server")
public class ServerProperties {
private String url;
private String username;
private String password;
// getters and setters
}
1
2
3
4
5
6
7
8
9
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Configuration;

@Configuration
@EnableConfigurationProperties(ServerProperties.class)
public class AppConfig {
// 这个类不需要有任何代码。
// 它的目的就是启用 ServerProperties。
}

在这个例子中,@EnableConfigurationProperties(ServerProperties.class) 告诉 Spring Boot 创建一个 ServerProperties 的 bean 并将属性绑定到它上,即使 ServerProperties 并没有被标记为 @Component

所以,总结一下:

  • @ConfigurationProperties 用于指定将要绑定到类上的属性的前缀。
  • @EnableConfigurationProperties 用于告诉 Spring Boot 创建带有 @ConfigurationProperties 注解的类的 bean。

value和ConfigurationProperties

@ConfigurationProperties@Value 是 Spring Framework 中用来处理外部配置的两种主要方式,它们都可以从外部源(如 application.properties 或 application.yml 文件)读取配置。然而,它们之间还是存在一些关键区别:

  1. 类型安全:@ConfigurationProperties 是类型安全的,也就是说,它会自动进行类型转换。例如,如果你有一个整数属性,而在配置文件中提供的值是字符串,Spring 会尝试将字符串值转换为整数。而 @Value 则不会进行这种类型转换,它会将所有配置值都当作字符串来处理。
  2. 校验支持:@ConfigurationProperties 可以和 Spring 的 JSR-303 校验(通过 @Validated 注解)结合使用,从而对配置属性进行校验。例如,你可以使用 @NotNull@Size 等注解来校验配置属性的值。相比之下,@Value 并不支持这种校验机制。
  3. 复杂类型:@ConfigurationProperties 支持复杂类型的配置,如列表和映射,也可以绑定到嵌套的 POJO。而 @Value 则仅支持简单类型。
  4. 表达式支持:@Value 可以使用 Spring 表达式语言 (SpEL),这让它在某些复杂的需要动态计算值的场景下更加有用。相比之下,@ConfigurationProperties 并不支持 SpEL。
  5. 批量配置:当你需要注入大量相关的属性时,@ConfigurationProperties 使得操作更加简洁,因为你可以在一个类中处理所有的相关属性。

总的来说,@Value 在处理简单的值或需要使用 SpEL 的场景下比较适用,而 @ConfigurationProperties 在处理复杂的、层次化的或需要进行校验的配置时更有优势。


ConfigurationProperties和EnableConfigurationProperties的区别
http://coder-xieshijie.cn/2023/07/31/Spring/ConfigurationProperties和EnableConfigurationProperties的区别/
作者
谢世杰
发布于
2023年7月31日
许可协议