# system-dict-starter
**Repository Path**: houkunlin/system-dict-starter
## Basic Information
- **Project Name**: system-dict-starter
- **Description**: 系统数据字典自动翻译成字典文本。可集合系统数据库中存储的用户数据字典,也可使用枚举做系统数据字典,主要用在返回数据给前端时自动把字典值翻译成字典文本信息。
- **Primary Language**: Java
- **License**: MulanPSL-2.0
- **Default Branch**: main
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 102
- **Forks**: 29
- **Created**: 2021-07-09
- **Last Updated**: 2026-08-16
## Categories & Tags
**Categories**: Uncategorized
**Tags**: java-util, SpringBoot, Jackson
## README
[](https://search.maven.org/search?q=g:%22com.houkunlin%22%20AND%20a:%22system-dict-starter%22)
[](https://github.com/houkunlin-starter/system-dict-starter/actions/workflows/gradle.yml)
# 系统字典 Starter
在日常项目开发中,不免都会用到一些数据字典的信息,以及前端展示的时候通常也需要把这些数据字典值转换成具体字典文本信息。遇到这种场景通常都是后端把字典的文本转换好一起返回给前端,前端只需要直接展示即可。
一般情况下后端可能需要单独给返回对象创建一个字段来存储对应的字典文本值,然后进行手动的处理,这种方式通常比较繁琐,在字段多的时候会增加更多的工作量。
本项目基于 Jackson 的自定义注解功能实现了这一自动转换过程,不需要在对象中定义存放字典文本的字段,只需要在字段上使用特定的注解配置,Jackson序列化的时候即可自动把字典值转换成字典文本。
**本项目只适用使用 Jackson 做 JSON 序列化,在 fastjson 下失效**
## 版本与依赖
**当前版本:`2.1.2`**
自 `v2.1.0` 起,本项目按 Spring Boot 版本拆分为三个独立的 Starter 模块,请根据项目使用的 Spring Boot 版本选择对应的依赖坐标。不同
Starter 使用不同的 Jackson 实现(Jackson 2 或 Jackson 3)。
| Starter 坐标 | 基于 SpringBoot 版本 | Java 版本 | Jackson |
|------------------------------------|----------------------|-----------|--------------------------------|
| `system-dict-spring-boot2-starter` | `2.7.18` | Java 8 | Jackson 2(`com.fasterxml.*`) |
| `system-dict-spring-boot3-starter` | `3.0.0` | Java 17 | Jackson 2(`com.fasterxml.*`) |
| `system-dict-spring-boot4-starter` | `4.0.1` | Java 17 | Jackson 3(`tools.jackson.*`) |
**Maven**
```xml
com.houkunlin
system-dict-spring-boot2-starter
${latest.version}
com.houkunlin
system-dict-spring-boot3-starter
${latest.version}
com.houkunlin
system-dict-spring-boot4-starter
${latest.version}
```
**Gradle**
```groovy
// Spring Boot 2.x
implementation "com.houkunlin:system-dict-spring-boot2-starter:${latest.release}"
// Spring Boot 3.x
implementation "com.houkunlin:system-dict-spring-boot3-starter:${latest.release}"
// Spring Boot 4.x
implementation "com.houkunlin:system-dict-spring-boot4-starter:${latest.release}"
```
## 历史版本兼容说明
| 版本 | 基于 SpringBoot 版本 | 测试兼容 SpringBoot 版本 |
|---------------------|-----------------------|--------------------------|
| `v1.5.8` 及以下 | `2.7.18` | `2.7.18` `3.4.5` |
| `v1.6.0` - `v1.6.4` | `3.4.6` | `3.4.6` |
| `v1.7.0` | `4.0.1` | `4.0.1` |
| `v2.0.0` 及以上 | 见上方 Starter 对照表 | - |
**`v1.5.8` 将成为最后一个基于 Java 8 字节码发布的版本(基于 Spring Boot 2.7)**
**从 `v1.4.11` 到 `v1.5.0` 版本产生了一些破坏性变更,请谨慎升级。移除了 DictText.Type 改为使用 DictBoolType;修改了 Redis
存储字典文本的方式,改为 Redis Hash 存储字典文本内容。**
**`v1.7.0` 适配 SpringBoot 4.x 版本,表现形式与 `v1.6.x` 一致,可直接进行升级。**
**从 `v1.7.0` 到 `v2.0.0` 版本产生了一些破坏性变更,请谨慎升级。涵盖:包名重构、独立 DictArray 注解、独立 DictTree
注解、移除非必要依赖(javassist、Swagger2)、核心序列化代码重构。**
## 版本特性
- **`v2.x`(当前)**:
- 修复 Jackson2 字典模块配置错误,改用直接注册 `DictJacksonModule` Bean 方式,避免
`Jackson2ObjectMapperBuilder.modules`
覆盖其他模块配置(`v2.1.2`)
- 修复 Redis/MQ 可选依赖下自动配置导致的启动失败问题;Redis 存储相关 Bean 仅在启用 Redis 存储 (`store-type` 为 `AUTO`
或 `REDIS`)时创建(`v2.1.1`)
- 按 Spring Boot 版本拆分 `system-dict-spring-boot2/3/4-starter` 三个独立模块
- 使用 ConverterFactory 实现枚举字典转换,默认支持枚举名称转换 + 字典值转换,移除 ASM 字节码依赖(`v2.0.3`)
- 重构缓存配置方式,使用 `system.dict.cache.caffeine.spec` 配置(`v2.0.2`)
- 枚举字典项支持自定义扩展属性(`v2.0.1`)
- 基于 Spring Boot 4.x 完全重构:包名重构、核心序列化代码重构、独立 `DictArray`/`DictTree` 注解、移除 javassist/Swagger2
依赖(`v2.0.0`)
- **`v1.7.x`**:适配 Spring Boot 4.x,重构 Jackson 配置方式,优化字典值/字典文本 JSON 输出代码,`DictValid3` 更名为
`DictValid`
- **`v1.6.x`**:基于 Spring Boot 3.4.6 / Java 17,重构字典枚举转换器初始化方式(改由 `WebMvcConfigurer#addFormatters`
注册),重构 Jackson 配置方式,缓存支持 `system.dict.cache.caffeine.spec` 配置
- **`v1.5.x`**:最后一个基于 Java 8 / Spring Boot 2.7 字节码发布的版本线,重构缓存存储方式(Redis Hash 存储字典文本)
#### 详细使用文档请点击查看 [基础用法文档](./usage.md)
#### 系统更新日志 [系统更新日志](./changelog.md)
## 如何启用?
- 在应用启动类上添加 `SystemDictScan` 注解
- 后续步骤请看本文后面内容
```java
// 启动类上加注解
@SystemDictScan
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class);
}
}
```
## 使用枚举对象做系统字典
- 需要实现 `DictEnum` 接口的枚举对象才能被扫描到
- 使用 `DictType` 注解应用到枚举上自定义字典类型名称和说明
> `@DictType` 用来标记枚举对象的字典类型代码
```java
@DictType(value = "PeopleType", comment = "用户类型")
@Getter
@AllArgsConstructor
public enum PeopleType implements DictEnum {
/** 系统管理员 */
ADMIN(0, "系统管理"),
/** 普通用户 */
USER(1, "普通用户"),
;
private final Integer value;
private final String title;
/**
* Jackson 枚举处理,把枚举值转换成枚举对象
*
* @param code 代码
* @return 枚举对象
*/
@JsonCreator
public static PeopleType getItem(Integer code) {
return DictEnum.valueOf(values(), code);
}
}
```
## 字典文本自动转换
- 在字段中使用 `DictText` 注解
```java
@Data
@AllArgsConstructor
class Bean {
@DictText("PeopleType")
private String userType1 = "1";
@DictArray(split = ",")
@DictText(value = "PeopleType")
private String userType2 = "1,2,3";
@DictArray(toText = false)
@DictText(value = "PeopleType")
private List userType3 = Arrays.asList("1", "2", "3");
}
```
## 提供一些其他字典信息到系统字典存储对象中
- 实现 `DictProvider` 接口并扫描到SpringBoot中
```java
@Component
public class MyProvider implements DictProvider {
@Override
public boolean isStoreDictType() {
return true;
}
@Override
public Iterator dictTypeIterator() {
// 从其他地方(其他服务、数据库、本地文件)加载完整的数据字典信息(字典类型+字典值列表)
// 从这里返回的数据字典信息将会被存入缓存中,以便下次直接调用,当有数据变动时可以发起 RefreshDictEvent 事件通知更新字典信息
final DictType typeVo = DictType.newBuilder("name", "测试字典")
.add("1", "测试1")
.add("2", "测试2")
.build();
return Collections.singletonList(typeVo).iterator();
}
}
```
## 当在系统字典中获取不到数据时,请求第三方服务获取字典信息
- 实现 `RemoteDict` 接口并扫描到SpringBoot中,当自行定义 `LocalDictStore` 对象时,此时的默认`RemoteDict`无法生效,需要手动处理此类情况。
- 例如无法从 `DictStore` 获取到字典信息时,可以使用 `RemoteDict` 从特定的系统服务中获取字典信息
```java
@Component
public class MyRemoteDict implements RemoteDict {
@Override
public DictType getDictType(final String type) {
// 从其他地方(其他服务、数据库、本地文件)加载一个完整的数据字典信息(字典类型+字典值列表)
return null;
}
@Override
public String getDictText(final String type, final String value) {
// 从其他地方(其他服务、数据库、本地文件)加载一个字典文本信息
return null;
}
}
```
## 全局工具类直接获取字典信息
- 调用 `DictUtil` 对象
```java
@Component
@AllArgsConstructor
public class CommandRunnerTests implements CommandLineRunner {
@Override
public void run(final String... args) throws Exception {
System.out.println(DictUtil.getDictText("PeopleType", "1"));
}
}
```