12-FAQ 与注意事项¶
📄 创建: ZCode AI 2026-08-14 · 修改: JimWb 2026-08-14
本篇汇总 SDK 使用中的已知问题、设计陷阱和历史遗留,帮助开发者和 AI 避坑。所有内容基于 dev 分支源码核实。
1. 异常双轨制¶
SDK 存在两个拼写相似的异常类,容易混淆:
| 类 | 继承 | 类型 | 拼写 | 使用场景 |
|---|---|---|---|---|
BussinessException |
RuntimeException | 非受检 | Bussiness(多一个 s) | 工具类(DateUtils/BeanUtils/SnowflakeIdWorker 等)抛这个 |
BussException |
BaseException → Exception | 受检 | Buss | 业务代码按需抛 |
BaseException |
Exception | 受检 | — | BussException 的父类 |
包路径:
- cn.cnbm.bams.common.exception.BussinessException
- cn.cnbm.bams.common.exception.BussException
- cn.cnbm.bams.common.exception.BaseException
建议:新代码用 BussinessException(非受检,无需 try-catch 或 throws 声明),与工具类保持一致。全局异常处理器(ExceptionHandlerConfig)两者都能捕获。
2. JSON 工具三套并存¶
| 工具 | 底层 | 包路径 | 推荐度 |
|---|---|---|---|
JsonUtils |
Jackson | common.utils.json.JsonUtils |
⭐ 推荐(新代码统一用) |
GsonUtils |
Gson | common.utils.GsonUtils |
辅助(泛型 List 解析、key 排序) |
hutool JSONUtil |
hutool | cn.hutool.json.JSONUtil |
局部使用 |
注意:
- JsonUtils 支持 JSON Path 取值、安静反序列化(失败返回 null)
- common-cache 的 RedisCacheManager 用 GsonUtils 序列化
- common-func 的 MyWebMvcConfigurer 配置的是 Jackson SNAKE_CASE
3. 安全风险:密钥硬编码¶
⚠️ 生产环境必须处理
| 类 | 问题 | 位置 |
|---|---|---|
JwtUtil |
JWT 签名密钥硬编码在 encryptJWTKey 字段 |
common.utils.JwtUtil |
RSAUtils |
RSA 公私钥硬编码在 Constants.RSA |
common.constant.Constants |
建议:
- 生产环境替换为从配置中心/环境变量读取
- 或通过 @ConfigurationProperties 注入
4. BaseEntity 子类 @EqualsAndHashCode 不统一¶
部分子类用了 @EqualsAndHashCode(callSuper = false),导致 BaseEntity 的 id/createdBy 等字段不纳入 equals/hashCode。
| callSuper=true(正确) | callSuper=false(遗留) |
|---|---|
| BdCorp, SysUser, SysRole, SysOperLog, PubSequence | BdDept, BdPerson, BdPost, BdUnit, BdDictionary, SysConfig, SysButton, SysMenuButton, SysTenantDb, PubFileUpload |
影响:两个 id 不同但业务字段相同的实体可能被判定为 equals。如果用到 Set/Map key 需注意。
建议:新实体一律 @EqualsAndHashCode(callSuper = true)。
5. 动态多数据源是半成品¶
bams-service 的 ext/ds/ 动态多数据源机制框架已就绪但未完全激活:
| 能力 | 状态 |
|---|---|
| AbstractRoutingDataSource + ThreadLocal 框架 | ✅ 完整 |
@TenantDataSource 注解 |
✅ 已定义 |
| DataSourceManager 管理数据源池 | ✅ 完整 |
| DataSourceInitService 启动加载 | ✅ 可用 |
| AOP 切面(注解→自动切换) | ❌ 缺失 |
| DynamicDataSource Bean 注册 | ❌ 未注册 |
影响:@TenantDataSource 注解目前不会自动切换数据源。
临时方案:手动调 DynamicDataSourceContext.setDataSourceKey(key),用完 clear()。
6. bams-file 旧版 FileClient 无入口¶
bams-file 的 service/core/client/ 下有完整的 FileClient 策略体系(DB/Local/FTP/SFTP/S3 五种实现 + 工厂),但:
- 2026-07-22(commit
82ca0ae)删除了入口FileController和FileConfigController - 此后该体系 Service 以下全部类无任何 Controller 注入
结论:旧版 FileClient 是孤儿代码,不要在新代码中使用。文件操作用新版 StorageProvider 体系。详见 06-文件管理。
7. Excel 转换器半成品¶
bams-file 的 convert/excel/ 下 4 个转换器:
| 转换器 | 状态 | 问题 |
|---|---|---|
MoneyConvert |
✅ 可用 | — |
JsonConvert |
✅ 可用 | — |
DictConvert |
⚠️ 半成品 | 字典查询逻辑被 TODO 注释(String value = ""; //DictFrameworkUtils...) |
AreaConvert |
⚠️ 不可用 | 解析逻辑整段注释,return 字面量 |
建议:只用 MoneyConvert/JsonConvert。字典转换用 common-func 的 ExcelHelper + @ExcelDictionaryColumn 代替。
8. Convert 与 hutool 同名冲突¶
cn.cnbm.bams.common.utils.text.Convert 与 cn.hutool.core.convert.Convert 同名。
问题:ListUtils、CalUtils 等类混用两者,import 时可能误引。
解决:使用时注意 import 的全限定名,或用全限定名调用:cn.cnbm.bams.common.utils.text.Convert.toInt(x)。
9. HttpClientUtil 可能存在重复¶
common.utils.HttpClientUtil 和 common.http.HttpClientUtil 两个同名类可能存在历史遗留的重复(文件移动未清理)。
HttpRequestUtil调用的是common.http.HttpClientUtil- 实际功能类在
common.utils.HttpClientUtil
建议:使用 common.utils.HttpClientUtil(功能更完整)。
10. DateUtils.stringToDateFormat 是巨型 if-else¶
DateUtils.stringToDateFormat(String) 方法按字符串长度和分隔符猜测日期格式(约 12 种),是"巨型 if-else"。
特点:兼容性强(什么格式都能猜),但维护性差。
建议:已知格式时优先用 dateTime(format, str)(明确指定格式),只在格式不确定时用 stringToDateFormat。
11. OrgInfo 不继承 BaseEntity¶
cn.cnbm.bams.pojo.bd.OrgInfo 不继承 BaseEntity,独立定义。它自带 @TableId(type=NONE) + @TableLogic isDeleted + 大量 fieldText1-15 / fieldDate1-4 / fieldNumber1-3 通用扩展字段。
原因:为对接外部"技术底座/中台"组织数据而设计的宽表 VO 类实体,字段结构不同于标准业务实体。
影响:不能享受 BaseEntity 的自动填充。如果需要审计字段,要自己处理。
12. 关联表实体不走 BaseEntity¶
以下实体不继承 BaseEntity,是轻量 POJO(仅 id + 关联字段):
SysUserRole(用户-角色)SysRoleResource(角色-资源)SysRoleButton(角色-按钮)SysAppRole(应用-角色)
影响:没有 createdBy/createdTime 等审计字段。如需审计,业务层自行处理。
13. BamsMetaObjectHandler 已废弃¶
common-permission 的 ibatis.handler.BamsMetaObjectHandler 整体已注释,仅保留空壳。
现状:已被 common-func 的 MyBatisPlusMetaObjectHandler 取代。不要尝试启用它。
14. TDengine type 是静态变量¶
tdengine 模块的 DbManager.type(JNI/REST 模式)是静态变量,全局影响所有实例。
影响:多数据源场景下,创建第二个 DbManager 实例时,type 会被覆盖。
建议:多 TDengine 数据源场景需谨慎管理实例创建时机,或统一用一种模式。
15. EnergyBaseController 写操作需配合 ISysLogService¶
EnergyBaseController 的写操作方法(/saveOrUpdate, /delete 等)带 @SysLog,会调 ISysLogService.save() 记录日志。
前提:应用需注入 ISysLogService Bean。如未配置,写操作会因找不到 Bean 而失败。
16. application.yml 配置项汇总¶
一份完整的配置项速查(按模块):
# === 数据权限(common-permission)===
project:
check-permission: true
dynamic:
datasource:
db-type: mysql
exclude-tables: sys_user,sys_role
# === Session ===
spring:
check-session:
enabled: true
# === 缓存(common-cache)===
project:
cache:
init-cache: true
init-taos: true
# === Kafka(bams-mq)===
project:
kafka:
consumer-enabled: true
send-topic: send-data
receive-topic-pattern: bams_.*
# === 文件上传(common-func)===
spring:
settings:
enable-table-auto-creation: true
# === Swagger ===
springdoc:
swagger:
title: "API 文档"
# === 版本 ===
project:
version:
enabled: true
path: /version
# === 流程引擎(bams-flow)===
bams:
flow:
enabled: true
warm-flow-enabled: true
lite-flow-enabled: true
相关文档¶
- SDK 开发包首页
- 03-通用工具库 — 异常/JSON/Convert 详解
- 04-实体与数据访问 — BaseEntity 继承
- 05-业务服务层 — 动态数据源
- 06-文件管理 — FileClient 孤儿代码