60-架构思想总结
Browise框架的六层架构思想——一个老兵的私有武器库是怎么设计的
59篇拆解完之后回头看,browise的技术选型背后有一套贯穿始终的架构思想。这篇提炼成六条主线——每条都是"在约束下做取舍"的结果,不是教科书搬运。
文章目录
思想一:元数据驱动——把"写代码"变成"填配置"
核心命题:政务系统80%的页面是"查询条件+结果列表+增删改查"——这80%不该写代码。
传统路径:需求 → Controller → Service → Mapper → XML → Vue页面
(5个文件,2天,改一个字段动全链)
browise路径:需求 → EA01-05五张表填配置 → <CommonQuery sqlId="xxx"/>
(一条元数据,30分钟,改字段改一行配置)
五张表描述任意SQL的本质——把SQL的结构(查什么、从哪查、怎么过滤、怎么排)拆成正交维度存进关系表,运行时按sqlId组装。结构化的东西才能配置化,配置化的东西才能零代码。
配套的翻译层设计是关键:
EAE009类型码 → 方言占位符(OracleDialect的to_date)
EAE991显示码 → 前端控件(mapDisplayType的date/number)
EAE997码值 → 字典翻译(ComboBox自动挂AA10)
同一份元数据,后端消费出SQL、前端消费出界面——一份配置两处产出。describe()接口(第13篇)是这个双向消费的协议出口。
逃生舱原则——五表覆盖90%,rawSql通道(第11篇)兜底10%复杂SQL。元数据引擎的边界必须清晰:它不做通用查询构建器(不支持顶层OR/子查询/函数条件),复杂需求去rawSql——两个通道没有灰色地带。
思想二:脏标记协议——前后端共享一份"变更语言"
核心命题:前后端分离后,"改了什么"的表示必须统一,否则每个接口都要自定义diff协议。
Row = { _t: 0|1|3|4, _o: {旧值}, ...业务字段 }
_t(行状态)+_o(原始值)两个字段,14年、三种语言(PB/Java/TS)、三代框架没变过。为什么这么稳——最小完备:
- 行级变更:一个枚举够了(NONE/INSERT/UPDATE/DELETE)
- 字段级回滚:一个旧值Map够了
- 再多的东西(修改时间/修改人)是业务字段,不属于协议
_o的复利效应是这套协议最值钱的地方——同一份旧值数据服务三个场景:
①rejectChanges回滚 → 从_o恢复(第19篇)
②UPDATE的WHERE → 用_o做乐观锁(第23篇)
③审计diff生成 → 遍历_o就是变更清单(第53篇)
设计时只想到①,②③是免费来的——协议做对了,复用会自己找上门。
三缓冲的取舍逻辑(第18篇)——primary/filter/delete三个ArrayList,remove时INSERT行不进delete缓冲(库里没它,无需同步)。每个缓冲的存在都对应一个真实需求,不是对称性设计的产物。
思想三:配置与引擎分离——变的和不变的分开放
核心命题:流程怎么流转(BPMN)和业务怎么处理(配置表)是两种变化频率的东西,必须物理分离。
引擎层(变得慢) 配置层(变得快)
───────────── ─────────────
Flowable 6.8 ACT_RE_BINDINGFORM 表单绑定
nextid网关协议 TASK_INTERCEPTOR_CONFIG 拦截器
completeTask三段式 ACT_PRCDAY 时限
ROLE_SET/OP_* 处理人
EA01-05 SQL元数据
变化频率决定存储位置——BPMN改一次要走"系统变更审批",配置表改一行是"参数调整"——政务系统的运维等级差异(第39篇)。拦截器从数据库读id串、表单绑定从配置表读sqlId——管理员改配置即刻生效,不碰流程定义。
引擎无关化的极限实践是CustomJdbcTransactionFactory——Activiti引擎的事务管理器被空壳化成继承MyBatis的JdbcTransaction(第35篇)——引擎与业务共用一个事务边界,这是"引擎为业务服务、不是业务迁就引擎"的彻底执行。
同样的分层在平台层——MenuAuthProvider的rolePaths十分钟刷新(第29篇)、system_cache的EA元数据全量装载+reset失效(第06篇)——低频变更数据全部走"启动预载+定时/手动刷新"的缓存模式,运行时纯内存判断。
思想四:模块正交——能力可插拔、依赖单向
核心命题:不是所有项目都要全部能力——模块按需装配,依赖关系不能成环。
common(无依赖)
← data(BaseEntity/RowSet——不依赖crypto!)
← crypto(SM全家桶——不依赖data)
← platform/workflow/metadata(业务模块)
starter(唯一的组装层)
← 把crypto桥接进data(EntityLifecycleListener)
← 条件装配:HSM优先→BC兜底→没有加密零开销
data不依赖crypto是全项目最重要的一条架构约束(第01篇)——BaseEntity需要加密能力但不能引入国密依赖——解法是data定义718B的接口、starter放桥接实现。两个模块互相看不见,靠接口契约协作。
条件装配金字塔(第32篇)的优先级链是安全语义——用户Bean > HSM > BC > 无。HSM优先不是技术考虑是等级考虑:合规要求时配置了HSM就该走HSM,即使BC的key也配了。
三重零开销降级——没配密钥→Sm4Crypto不存在→CryptoHelper不存在→CryptoAspect不存在→BaseMapper调用零AOP开销。功能关闭的成本必须是零,这是可插拔的最低标准。
思想五:事务边界显式化——谁开始谁负责
核心命题:分布式事务不搞,单库事务的边界必须清晰可见。
模式一:EaEngine的myTrans
if (!provider.hasTransaction()) → 自己begin/commit/rollback
else → 只执行SQL还连接,事务交给外层
(success-flag:只有成功路径commit——第06篇)
模式二:saveBatch的openSession(false)
手动commit/全量rollback——批处理原子性(第24篇)
模式三:Spring @Transactional
AuthService/CountersignService等业务Service层声明
引擎检测到外层事务自动并入
myTrans检测是这套体系的枢纽——同一份引擎代码,独立调用时自管事务、被事务包裹时自动并入。commonSave没有默认事务(第23篇)是刻意决策:通用Controller不敢开长事务(逐行EA执行行数大时锁持有不可控),事务边界留给知道业务规模的上层。
事务后事件(第43篇)是这个思想的延伸——推送必须在afterCommit——"数据已持久化"是推送的前置条件,注册TransactionSynchronization而不是立即publish。
思想六:安全内建——不是功能是地基
核心命题:国密/审计/脱敏不是后期加的功能模块,是数据通路的地基。
数据流向的每一跳都有安全检查:
写入:@EncryptedField → CryptoAspect拦截 → 先签后密 → 库里密文
BaseEntity save → AuditEntityLifecycleListener → 三表审计快照
查询:EA引擎postProcess → 先解密再脱敏 → 输出的永远不是原值
JwtAuthFilter九步 → 认证+黑名单+禁用检查+菜单RBAC
运维:OpsService四道闸 → 预览备份→影响预估→行数截断→硬熔断
OPS_SQL_LOG → 谁何时跑了什么SQL全记录
加密在引擎层做不在Controller层做(第14/15篇)——只要走EA查询,脱敏必发生,没有API能绕过。审计复用_o(第53篇)——脏标记协议免费提供字段级diff,审计不用二次对比。
96个评审问题的价值(第34篇)——最危险的三段组合链(无鉴权+SQL拼接+rawSql)单段无害组合致命——评审必须跨模块看组合面,这是单测覆盖不了的盲区。
六条思想的共同内核
| 思想 | 一句话 | 反面教材 |
|---|---|---|
| 元数据驱动 | 结构化的东西配置化 | 每个页面手写五层代码 |
| 脏标记协议 | 变更的表示前后端统一 | 每个接口自定义diff格式 |
| 配置与引擎分离 | 按变化频率决定存储位置 | 改个审批人要重新部署流程 |
| 模块正交 | 能力可插拔零开销降级 | 不用加密也被迫引国密依赖 |
| 事务边界显式 | 谁开始谁负责可并入 | 事务包裹层级不明部分提交 |
| 安全内建 | 数据通路每跳有检查 | 上线前突击加脱敏 |
共同内核:约束下的取舍。政务场景的约束——国产化数据库、国密合规、单机部署、小团队、需求高频变更——每条思想都是针对这些约束的最优解而不是理想解。多实例扩展弱、监控可观测弱、无社区——这些短板不是不知道,是约束下主动放弃的(单机政务应用用不上K8s级可观测性)。
这套思想的可迁移性——离开政务场景,元数据驱动/脏标记协议/配置引擎分离三条照样成立(任何CRUD密集型系统);模块正交和事务显式是普适原则;安全内建看合规等级。架构思想的价值不在browise这个实现,在"遇到类似约束时这套取舍逻辑可以复用"。
✅ 亮点:六条主线从59篇拆解中提炼、每条配"核心命题+机制+反面教材"、_o复利三场景与三重零开销降级两个最深设计的展开、最后归结到"约束下的取舍"并给出可迁移性判断。适合做架构评审或技术选型的人。扩展方向:59篇系列任何一篇都是某条思想的代码级展开。
更多推荐




所有评论(0)