在本文中,您将学习如何通过名为 @ConfigurationProperties
的非常简单的基于注解的 API 在 Spring Boot 中定义和使用外部配置。
@ConfigurationProperties
将外部配置绑定到应用程序代码中的强类型 bean。您可以像任何其他 spring bean 一样在整个应用程序代码中注入和使用这个 bean。
让探索开始吧!
让我们创建一个示例应用程序来学习如何在 Spring Boot 中定义和使用外部配置。
我们将使用 Spring Boot CLI 来初始化项目。启动终端并输入以下命令以生成项目 -
spring init --dependencies=web,validation --name=config-properties-demo --package-name=com.example.demo config-properties-demo
或者,您也可以按照以下说明从 Spring Initializr 网站引导应用程序 -
config-properties-demo
。com.example.demo
Web
和 Validation
。以下是完整应用的目录结构,供大家参考——
Spring Boot 应用程序默认从位于类路径中的 application.properties
文件加载配置属性。
打开 src/main/resources/application.properties
文件并向其添加以下属性 -
## Top level app properties
app.name=ConfigurationPropertiesDemoApp
app.description=${app.name} is a spring boot app that demonstrates how to use external configuration properties
app.upload-dir=/uploads
app.connect-timeout=500ms
app.read-timeout=10s
## Nested Object Properties (security)
app.security.username=callicoder
app.security.password=123456
app.security.roles=USER,ADMIN,PARTNER # List Property
app.security.enabled=true
## Map Properties (permissions)
app.security.permissions.CAN_VIEW_POSTS=true
app.security.permissions.CAN_EDIT_POSTS=true
app.security.permissions.CAN_DELETE_POSTS=false
app.security.permissions.CAN_VIEW_USERS=true
app.security.permissions.CAN_EDIT_USERS=true
app.security.permissions.CAN_DELETE_USERS=false
现在让我们看看如何使用 @ConfigurationProperties
将 application.properties
文件中定义的属性绑定到 POJO 类。
@ConfigurationProperties
注释采用 prefix
参数,并将具有指定前缀的所有属性绑定到 POJO 类 -
package com.example.demo.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.convert.DurationUnit;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@ConfigurationProperties(prefix = "app")
public class AppProperties {
private String name;
private String description;
private String uploadDir;
private Duration connectTimeout = Duration.ofMillis(1000);
@DurationUnit(ChronoUnit.SECONDS)
private Duration readTimeout = Duration.ofSeconds(30);
private final Security security = new Security();
// Getters and Setters (Omitted for brevity)
public static class Security {
private String username;
private String password;
private List<String> roles = new ArrayList<>();
private boolean enabled;
private Map<String, String> permissions = new HashMap<>();
// Getters and Setters (Omitted for brevity)
}
}
让我们了解有关绑定的一些细节:
类型安全绑定(列表和映射)
注意属性文件中逗号分隔的 roles
是如何绑定到角色的 List
的,而 permissions
是绑定到 Map
的。
*
持续时间支持
另外,请注意持续时间属性如何安全地绑定到 Duration
类型。这太棒了。 Spring Boot 允许您在 application.properties
文件中使用以下单位指定持续时间 -
ns
纳秒us
为微秒ms
毫秒s
秒m
分钟h
数小时d
几天默认单位是 milliseconds
。所以如果你没有在属性文件中指定任何单位,它会被认为是 milliseconds
。
请注意,您也可以使用 @DurationUnit
注释覆盖单元,就像我们在上面的 POJO 类中所做的那样。
命名约定
所有 kebab case 属性名称(例如:upload-dir)都绑定到 POJO 类中相应的驼峰式大小写字段(例如:uploadDir)。
请注意,也可以在驼峰式大小写中指定属性。但建议使用烤肉串。
您需要使用 @EnableConfigurationProperties
注释显式注册属性类,如下例所示。
package com.example.demo;
import com.example.demo.config.AppProperties;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
@SpringBootApplication
@EnableConfigurationProperties(AppProperties.class)
public class ConfigPropertiesDemoApplication {
public static void main(String[] args) {
SpringApplication.run(ConfigPropertiesDemoApplication.class, args);
}
}
或者,您还可以向 AppProperties
类添加 @Component
注释,并且绑定仍然有效。
@ConfigurationProperties
类是普通的 spring bean,您可以像注入任何其他 bean 一样注入它们。
在下面的示例中,我编写了一个示例 API,它从配置属性中检索应用程序详细信息并将它们返回给客户端 -
package com.example.demo.controller;
import com.example.demo.config.AppProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.Map;
@RestController
public class IndexController {
// Injecting ConfigurationProperties in your Beans
@Autowired
private AppProperties appProperties;
@GetMapping("/")
public Map<String, String> getAppDetails() {
Map<String, String> appDetails = new HashMap<>();
appDetails.put("name", appProperties.getName());
appDetails.put("description", appProperties.getDescription());
return appDetails;
}
}
您可以使用 javax.validation
约束(如 @NotNull
、@NotEmpty
等)来验证配置属性。
要启用验证,您只需要在 @ConfigurationProperties
类中添加 Spring 的 @Validated
批注 -
package com.example.demo.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.convert.DurationUnit;
import org.springframework.validation.annotation.Validated;
import javax.validation.Valid;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@ConfigurationProperties(prefix = "app")
@Validated
public class AppProperties {
@NotNull
private String name;
private String description;
private String uploadDir;
private Duration connectTimeout = Duration.ofMillis(1000);
@DurationUnit(ChronoUnit.SECONDS)
private Duration readTimeout = Duration.ofSeconds(30);
@Valid
private final Security security = new Security();
// Getters and Setters (Omitted for brevity)
public static class Security {
private String username;
private String password;
@NotEmpty
private List<String> roles = new ArrayList<>();
private boolean enabled;
private Map<String, String> permissions = new HashMap<>();
// Getters and Setters (Omitted for brevity)
}
}
现在,如果 name
属性为 null
或 security.roles
属性为空,Spring Boot 应用程序将在启动时抛出验证异常。
除了标准的 application.properties
文件之外,Spring Boot 还允许您使用以下命名约定定义特定于配置文件的属性 -
application-{profile}.properties
配置文件特定的属性文件从与 application.properties
文件相同的位置加载,配置文件特定的属性始终覆盖默认属性。
为了说明这一点,让我们定义一些特定于配置文件的属性文件,并覆盖一些默认属性 -
应用程序-dev.properties
## Override properties for dev environment
app.name=ConfigurationPropertiesDemoApp-DEVELOPMENT
app.security.username=callicoder-dev
application-staging.properties
## Override properties for staging environment
app.name=ConfigurationPropertiesDemoApp-STAGING
app.security.username=callicoder-staging
app.security.password=C@ll1C0d3r
应用程序-prod.properties
## Override properties for prod environment
app.name=ConfigurationPropertiesDemoApp-PRODUCTION
app.security.username=callicoder-prod
app.security.password=C@ll1C0d3r
现在,我们需要激活一个 spring 配置文件,以便 spring boot 加载相应的属性文件。
您可以通过多种方式设置活动配置文件 -
使用应用程序属性
默认的 application.properties
文件总是由 Spring Boot 加载。您可以通过添加以下属性在 application.properties
文件中设置活动配置文件 -
spring.profiles.active=staging
后添加上述属性,Spring Boot 也会加载 application-staging.properties
文件,并使用在那里指定的新值覆盖属性。
1.
使用命令行参数
您可以通过提供 spring.profiles.active
命令行参数来设置启动时的活动配置文件 -
# Packaging the app
mvn clean package -Dspring.profiles.active=staging
# Running the packaged jar with `spring.profiles.active` argument
java -jar -Dspring.profiles.active=staging target/config-properties-demo-0.0.1-SNAPSHOT.jar
此外,这是在使用 spring-boot:run
命令运行应用程序时设置活动配置文件的方法 -
mvn spring-boot:run -Dspring.profiles.active=dev
使用环境变量
最后,您还可以使用 SPRING_PROFILES_ACTIVE
环境变量设置活动配置文件-
export SPRING_PROFILES_ACTIVE=prod
让我们运行应用程序并访问示例 Rest API 以查看操作中的配置属性 -
mvn spring-boot:run
$ curl http://localhost:8080
{"name":"ConfigurationPropertiesDemoApp","description":"ConfigurationPropertiesDemoApp is a spring boot app that demonstrates how to use external configuration properties"}
使用设置为 prod 的活动配置文件运行应用程序
mvn spring-boot:run -Dspring.profiles.active=prod
$ curl http://localhost:8080
{"name":"ConfigurationPropertiesDemoApp-PRODUCTION","description":"ConfigurationPropertiesDemoApp-PRODUCTION is a spring boot app that demonstrates how to use external configuration properties"}
@ConfigurationProperties
是一种以类型安全的方式绑定外部配置的非常好的方法。我几乎在所有项目中都使用此功能。此外,Spring Boot 的自动配置也依赖于配置属性。
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://www.callicoder.com/spring-boot-configuration-properties-example/
内容来源于网络,如有侵权,请联系作者删除!