目录
一、业务背景
在软件开发中,配置管理是确保应用程序能够在不同环境中灵活运行的关键环节。对于 Spring Boot 项目,配置文件(如
application.yml
或application.properties
)通常用于存储各种配置项,如数据库连接信息、服务端口、API密钥等。然而,随着业务逻辑的复杂化,直接使用字符串或数字作为配置项可能会导致代码的可读性和可维护性下降。枚举类(Enum) 提供了一种将一组固定的值封装在一起的方法,这不仅提高了代码的可读性,还能避免硬编码(
magic number
)带来的潜在问题。通过将业务中的固定状态、类型等内容定义为枚举,可以使得代码更加严谨和可维护。例如,用户角色、订单状态、支付方式等都可以通过枚举来管理。在实际业务中,可能需要根据不同的环境或配置动态调整这些枚举值。
@ConfigurationProperties
注解允许开发者将外部配置文件中的内容映射到 Java 类中,从而实现配置的动态管理。结合枚举类和@ConfigurationProperties
,可以实现一种高效、灵活且易于维护的配置管理方式。
二、配置管理缺点
在 Spring Boot 项目中,配置管理通常通过
application.yml
或application.properties
文件来实现。
可读性差: 代码中直接使用字符串或数字,难以理解其含义。
维护成本高: 修改配置时需要在多处查找和替换,容易出错。
硬编码问题: 直接使用字符串或数字容易导致潜在的错误。
三、解决方案
在 Spring Boot 项目中结合 Enum 和 @ConfigurationProperties
实现配置化管理。
四、实现代码
-
项目依赖: 使用 Maven 的
pom.xml
文件定义项目依赖,包括Spring Boot Starter Web
、Thymeleaf
模板引擎和 Lombok。 -
配置文件: 在 application.yml 文件中定义用户类型的配置。
-
枚举类: 定义一个
UserTypeEnum
枚举类,包含三种用户类型及其描述。 -
配置类: 使用
@ConfigurationProperties
注解将配置文件中的内容映射到 Java 类中。 -
控制器: 创建一个控制器类
UserController
,用于处理/user-types
请求,并将用户类型的描述传递到前端。 -
前端页面: 使用 Thymeleaf 模板引擎渲染从后端传递过来的数据,展示用户类型的描述。
1、项目依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
2、配置文件
spring:
thymeleaf:
# THYMELEAF (ThymeleafAutoConfiguration)
# 开启模板缓存(默认值: true )
cache: true
# 检查模板是否存在,然后再呈现
check-template: true
# 检查模板位置是否正确(默认值 :true )
check-template-location: true
#Content-Type 的值(默认值: text/html )
content-type: text/html
# 开启 MVC Thymeleaf 视图解析(默认值: true )
enabled: true
# 模板编码
encoding: UTF-8
# 要被排除在解析之外的视图名称列表,⽤逗号分隔
excluded-view-names:
# 要运⽤于模板之上的模板模式。另⻅ StandardTemplate-ModeHandlers( 默认值: HTML5)
mode: HTML5
# 在构建 URL 时添加到视图名称前的前缀(默认值: classpath:/templates/ )
prefix: classpath:/templates/
# 在构建 URL 时添加到视图名称后的后缀(默认值: .html )
suffix: .html
server:
# 应用服务 WEB 访问端口
port: 8080
#配置初始化枚举值
app:
user-type:
admin: ADMIN
user: USER
guest: GUEST
3、枚举类
public enum AppEnum {
ADMIN("管理员"),
USER("普通用户"),
GUEST("游客");
private final String description;
AppEnum(String description) {
this.description = description;
}
public String getDescription() {
return description;
}
}
详细说明
-
UserTypeEnum
是一个枚举类,定义了三种用户类型:管理员(ADMIN
)、普通用户(USER
)和游客(GUEST
)。 -
每种用户类型都有一个描述(
description
),用于提供对应的中文描述。 -
枚举常量声明:
-
ADMIN 对应 "管理员"。
-
USER 对应 "普通用户"。
-
GUEST 对应 "游客"。
-
-
构造函数
UserTypeEnum(String description)
用于初始化枚举常量的描述。 -
getDescription
方法返回对应的描述。
4、配置类
使用 @ConfigurationProperties
注解将配置文件中的内容映射到 Java 类中,并使用 Enum 来表示这些配置项。
import com.example.springbootenum.demos.enums.AppEnum;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Data
@Component
@ConfigurationProperties(prefix = "app")
public class AppConfig {
private UserType userType;
@Data
public static class UserType{
private AppEnum admin;
private AppEnum user;
private AppEnum guest;
}
}
详细说明
-
AppConfig
类是一个 Spring 配置类,用于加载和存储应用程序配置。 -
@Data
注解来自 Lombok,自动生成getter
、setter
、toString
、equals
和hashCode
方法。 -
@Component
注解将类标记为 Spring 组件,以便在 Spring 容器中进行管理。 -
@ConfigurationProperties(prefix = "app")
注解将类标记为配置属性类,并指定配置前缀为 "app"。 -
AppConfig
类包含一个嵌套的静态类UserType
,用于定义用户类型的配置:-
admin 对应管理员用户类型。
-
user 对应普通用户类型。
-
guest 对应游客用户类型。
-
5、控制器
import com.example.springbootenum.demos.config.AppConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
@Controller
@RequestMapping("/app")
public class AppController {
@Autowired
private AppConfig appConfig;
@GetMapping("/getAllRole")
public ModelAndView getAllRole(ModelAndView modelAndView){
modelAndView.addObject("admin",appConfig.getUserType().getAdmin());
modelAndView.addObject("user",appConfig.getUserType().getUser());
modelAndView.addObject("guest",appConfig.getUserType().getGuest());
modelAndView.setViewName("index");
return modelAndView;
};
}
6、Thymeleaf前端页面
通过 Thymeleaf
模板引擎渲染从后端传递过来的数据。
在 src/main/resources/templates
目录下创建 index.html
文件
<html>
<head>
<meta charset="UTF-8">
<title>用户类型</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css">
</head>
<body>
<div class="container">
<h1 class="mt-5">用户类型</h1>
<table class="table table-bordered mt-3">
<thead>
<tr>
<th>角色</th>
<th>描述</th>
</tr>
</thead>
<tbody>
<tr>
<td>ADMIN</td>
<td th:text="${admin}"></td>
</tr>
<tr>
<td>USER</td>
<td th:text="${user}"></td>
</tr>
<tr>
<td>GUEST</td>
<td th:text="${guest}"></td>
</tr>
</tbody>
</table>
</div>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>