# dyenums
**Repository Path**: itcraft-cn/dyenums
## Basic Information
- **Project Name**: dyenums
- **Description**: 一个支持 Java 8+ 的动态枚举库。与编译期固定的传统 Java 枚举不同,dyenums 允许你在运行时注册、修改和加载枚举值。
- **Primary Language**: Unknown
- **License**: Apache-2.0
- **Default Branch**: main
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2026-03-11
- **Last Updated**: 2026-03-11
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# dyenums - Java 动态枚举库
[](https://www.oracle.com/java/)
[](https://maven.apache.org/)
[](https://opensource.org/licenses/Apache-2.0)
**dyenums** 是一个支持 Java 8+ 的动态枚举库。与编译期固定的传统 Java 枚举不同,dyenums 允许你在运行时注册、修改和加载枚举值。
## 核心特性
- **运行时注册**:在运行时动态注册枚举值
- **配置加载**:从属性文件或数据库加载枚举(可选)
- **自定义加载器**:实现 `DyEnumsLoader` 接口支持任意数据源
- **类型安全**:使用泛型确保编译期类型检查
- **线程安全**:基于 `ConcurrentHashMap` 和同步机制实现
- **最小核心**:核心模块仅依赖 SLF4J
- **Spring 集成**:可选的 Spring/Boot 支持
## 模块结构
```
dyenums
├── dyenums-core # 核心模块(必需)- 最小依赖
├── dyenums-loader-file # 文件加载器(可选)- 属性文件支持
├── dyenums-loader-db # 数据库加载器(可选)- JDBC 支持
└── dyenums-spring # Spring 集成(可选)- 自动配置
```
| 使用场景 | 需要的模块 |
|----------|-----------|
| 手动注册 | `dyenums-core` |
| 自定义加载器 | `dyenums-core` |
| 从属性文件加载 | `dyenums-core` + `dyenums-loader-file` |
| 从数据库加载 | `dyenums-core` + `dyenums-loader-db` |
| Spring/Boot 集成 | `dyenums-core` + `dyenums-spring` |
## 安装
### Maven
**仅核心模块(最小依赖)**:
```xml
cn.itcraft
dyenums-core
1.0.0
```
**添加文件加载器**:
```xml
cn.itcraft
dyenums-loader-file
1.0.0
```
**添加数据库加载器**:
```xml
cn.itcraft
dyenums-loader-db
1.0.0
```
**添加 Spring 集成**:
```xml
cn.itcraft
dyenums-spring
1.0.0
```
### 从源码构建
```bash
git clone https://github.com/itcraft-cn/dyenums.git
cd dyenums
mvn clean install
```
## 快速开始
### 1. 定义枚举类
继承 `BaseDyEnum`:
```java
import cn.itcraft.dyenums.core.BaseDyEnum;
public class UserStatus extends BaseDyEnum {
public static final UserStatus ACTIVE = new UserStatus("ACTIVE", "激活", "用户已激活", 1);
public static final UserStatus INACTIVE = new UserStatus("INACTIVE", "未激活", "用户未激活", 2);
public static final UserStatus LOCKED = new UserStatus("LOCKED", "锁定", "用户被锁定", 3);
private UserStatus(String code, String name, String description, int order) {
super(code, name, description, order);
}
}
```
### 2. 注册和使用
```java
import cn.itcraft.dyenums.core.EnumRegistry;
public class Application {
public static void main(String[] args) {
// 注册预定义值
EnumRegistry.register(UserStatus.class, UserStatus.ACTIVE);
EnumRegistry.register(UserStatus.class, UserStatus.INACTIVE);
EnumRegistry.register(UserStatus.class, UserStatus.LOCKED);
// 按 code 查询
UserStatus status = EnumRegistry.valueOf(UserStatus.class, "ACTIVE")
.orElseThrow(() -> new IllegalArgumentException("状态不存在"));
System.out.println(status.getName()); // 输出: 激活
}
}
```
## 高级用法
### 动态注册
```java
// 运行时创建并注册
UserStatus customStatus = new UserStatus("CUSTOM", "自定义状态", "自定义状态", 99);
EnumRegistry.register(UserStatus.class, customStatus);
// 或使用反射通过 EnumRegistry.addEnum
EnumRegistry.addEnum(UserStatus.class, "VIP", "VIP用户", "VIP状态", 100);
```
### 自定义加载器
实现 `DyEnumsLoader` 接口从任意数据源加载:
```java
import cn.itcraft.dyenums.loader.DyEnumsLoader;
import cn.itcraft.dyenums.core.DyEnum;
import java.util.function.BiFunction;
public class MyCustomLoader implements DyEnumsLoader {
@Override
public int load(Class enumClass, BiFunction factory) throws Exception {
// 从你的数据源加载(REST API、Redis 等)
List dataList = fetchFromMySource();
int count = 0;
for (MyData data : dataList) {
String code = data.getCode();
String valueString = data.getName() + "|" + data.getDesc() + "|" + data.getOrder();
T enumValue = factory.apply(code, valueString);
EnumRegistry.register(enumClass, enumValue);
count++;
}
return count;
}
@Override
public boolean validateSource() {
return isMySourceAccessible();
}
}
```
### 多语言支持
扩展支持多语言消息:
```java
import cn.itcraft.dyenums.core.BaseDyEnum;
import java.util.Locale;
import java.util.Map;
import java.util.HashMap;
public class ErrorCode extends BaseDyEnum {
private final Map messages;
public ErrorCode(String code, String name, int order, Map messages) {
super(code, name, null, order);
this.messages = messages;
}
public String getMessage(String lang) {
return messages.getOrDefault(lang, getCode());
}
public String getMessage(Locale locale) {
return getMessage(locale.getLanguage());
}
// 便捷方法
public String getMessageZh() { return getMessage("zh"); }
public String getMessageEn() { return getMessage("en"); }
}
// 使用示例
Map messages = new HashMap<>();
messages.put("zh", "系统错误");
messages.put("en", "System error");
messages.put("pt", "Erro do sistema");
messages.put("ru", "Системная ошибка");
ErrorCode error = new ErrorCode("SYS_001", "系统错误", 1, messages);
EnumRegistry.register(ErrorCode.class, error);
System.out.println(error.getMessageZh()); // 系统错误
System.out.println(error.getMessageEn()); // System error
```
### 从属性文件加载
使用 `dyenums-loader-file` 模块:
```properties
# enums.properties
UserStatus.ACTIVE=ACTIVE|激活|用户已激活|1
UserStatus.INACTIVE=INACTIVE|未激活|用户未激活|2
```
```java
import cn.itcraft.dyenums.loader.file.FileBasedDyEnumsLoader;
FileBasedDyEnumsLoader loader = new FileBasedDyEnumsLoader<>("enums.properties");
loader.load(UserStatus.class, UserStatus::fromValueString);
```
### 从数据库加载
使用 `dyenums-loader-db` 模块:
```java
import cn.itcraft.dyenums.loader.db.DatabaseDyEnumsLoader;
import javax.sql.DataSource;
DatabaseDyEnumsLoader loader = new DatabaseDyEnumsLoader<>(dataSource);
loader.load(UserStatus.class, UserStatus::fromValueString);
```
### Spring 集成
使用 `dyenums-spring` 模块:
```java
import cn.itcraft.dyenums.spring.EnumService;
import org.springframework.beans.factory.annotation.Autowired;
@Service
public class UserService {
@Autowired
private EnumService enumService;
public List getAllStatuses() {
return enumService.getValues(UserStatus.class);
}
public UserStatus getStatus(String code) {
return enumService.getByCode(UserStatus.class, code);
}
}
```
## 架构设计
```
┌─────────────────────────────────────────────────────────────┐
│ 应用层 │
├─────────────────────────────────────────────────────────────┤
│ EnumRegistry (Core) - 注册、查询、线程安全 │
├──────────────┬──────────────┬──────────────┬────────────────┤
│ BaseDyEnum │ DyEnumsLoader│ @EnumDef │ Spring Config │
│ (Core) │ (Core 接口) │ │ (可选) │
├──────────────┴──────────────┴──────────────┴────────────────┤
│ 可选加载器实现 │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────────┐│
│ │ 文件加载器 │ │ 数据库加载器 │ │ 自定义实现 ││
│ │ (可选) │ │ (可选) │ │ (自行实现) ││
│ └─────────────┘ └─────────────┘ └─────────────────────────┘│
└─────────────────────────────────────────────────────────────┘
```
### 核心组件
| 组件 | 模块 | 说明 |
|------|------|------|
| `DyEnum` | core | 枚举接口定义 |
| `BaseDyEnum` | core | 抽象基类实现 |
| `EnumRegistry` | core | 枚举实例中央注册表 |
| `DyEnumsLoader` | core | 自定义加载器接口 |
| `FileBasedDyEnumsLoader` | loader-file | 属性文件加载器 |
| `PropDyEnumsLoader` | loader-file | 内存 Properties 加载器 |
| `DatabaseDyEnumsLoader` | loader-db | JDBC 数据库加载器 |
| `EnumService` | spring | Spring 枚举访问服务 |
| `EnumConverter` | spring | Spring MVC 类型转换器 |
## 测试
```bash
# 运行所有测试
mvn test
# 运行特定模块测试
mvn test -pl dyenums-core
mvn test -pl dyenums-loader-file
# 运行特定测试类
mvn test -Dtest=EnumRegistryTest
```
## 线程安全
所有注册表操作都是线程安全的:
```java
// 支持并发访问
ExecutorService executor = Executors.newFixedThreadPool(10);
for (int i = 0; i < 100; i++) {
final int id = i;
executor.submit(() -> {
EnumRegistry.addEnum(UserStatus.class, "STATUS_" + id, "状态 " + id, null, id);
});
}
executor.shutdown();
executor.awaitTermination(1, TimeUnit.MINUTES);
assertEquals(100, EnumRegistry.getCount(UserStatus.class));
```
## 性能特性
- **O(1) 查询**:基于 HashMap 的 code 查询
- **并发访问**:`ConcurrentHashMap` 保证线程安全
- **惰性初始化**:枚举仅在注册时创建
- **内存高效**:共享单一注册表实例
## 最佳实践
1. 在应用启动时注册枚举
2. 枚举实例创建后视为不可变
3. 确保 code 在同一枚举类型内唯一
4. 为自定义数据源实现 `DyEnumsLoader`
5. Spring 应用中使用 `EnumService`
## 贡献
1. Fork 本仓库
2. 创建特性分支 (`git checkout -b feature/AmazingFeature`)
3. 提交更改 (`git commit -m 'feat: add AmazingFeature'`)
4. 推送到分支 (`git push origin feature/AmazingFeature`)
5. 创建 Pull Request
## 许可证
本项目基于 Apache License 2.0 许可 - 详见 [LICENSE](LICENSE) 文件。
## 支持
- 在 GitHub 创建 Issue
- 查看 `doc` 目录中的文档
- 参考 `dyenums-test` 模块中的示例实现