业务上下文开发指南
业务侧希望有一套机制,可以获取当前用户、所属组织等上下文信息。目前用户上下文是可以通过 TContext 获取到的, 不过所属组织等上下文信息暂不可以。
在这之前业务实现组织上下文的方式,一般是通过 HttpFilter 将该信息提前放到上下文中的,然后其他模块用到该上下文的地方,都需要引入这个filter及对应的实现逻辑,这可能会引入不必要的过大依赖。
通过以下方式可以定义业务上下文,其他模块需要使用到该上下文的地方,仅需引入该接口便可。
在线编辑上下文
进入 制品中心->配置->业务域->业务上下文,业务上下文:
创建业务上下文
- 关于业务上下文的在线化创建方式跟扩展点差不多,点击左侧的业务上下文菜单,打开管理列表

- 点击右上角的【创建】按钮打开创建窗口
填写资源标识、名称、过期时间以及方法声明列表后,点击【提交】即可在线创建业务上下文资源

其中
| 字段 | 类型 | 规则 |
|---|---|---|
| 资源原标识 | string | 必填,50字以内的大写字母、小写字母或数字组合,必须大写字母开头,编辑时不可修改 |
| 名称 | string | 必填,50个字以内的无限制字符 |
| 过期时间 | int | 必填,单位秒,默认300 |
| 描述 | string | 非必填,200个字以内的无限制格式字符 |
| 方法名 | String | 方法名必须以get开头,支持字母、数字和下划线_的组合,且长度不能超出50个字符 eg:getUserId、getCurrentContext135 |
| 出参类型 | dictionary | 非必填,不填出参为void。枚举为:模型、模型数组、模型分页、List(集合)、Map(映射)、自定义 默认为:模型 |
| 出参模型 | link 模型 | 入参模型、常见数据类型、自定义类型全限定名三者之一必填 可选范围为当前应用版本下所有模型 |
| 常见数据类型 | dictionary | 入参模型、常见数据类型、自定义类型全限定名三者之一必填 |
| 自定义类型全限定类名 | string | 入参模型、常见数据类型、自定义类型全限定名三者之一必填 必须填写Java类全限定名, eg:java.lang.String、io.terminus.trantor.base.User 当出/入参类型为映射(Map)时,只能在这里填写参数化类型列表,且必须使用英文字符逗号作为分隔符 eg:java.lang.String, java.lang.Long |

定义上下文实现
一般来说, 声明了业务上下文的模块, 也会声明其实现, 以描述获取上下文真实逻辑:
- 业务上下文实现是一个 Java Class
- 该 Class 需要实现对应 业务上下文声明的 Interface
- 需要在该 Class 打上 @BusinessContextImpl 的注解, 并声明相关信息
- 实现相关获取上下文的方法, 方法内可以使用 TContext.getCurrentUser()
- 实现需要使用其他 LogicFlow 或者 LogicFunction, 可以直接使用成员声明, 通过构造器注入的方式使用
- 特别注意方法必须无参,且以 getXxx() 开头, 另外可以多个方法
@BusinessContextImpl(name = "Trade context")@AllArgsConstructorpublic class TradeContextImpl implements TradeContext {
private final LoadCurrentBusinessEntityFunc loadCurrentBusinessEntityFunc;
// 获取业务主体 public BusinessEntityBO getBusinessEntity() { User user = TContext.getCurrentUser(); return loadCurrentBusinessEntityFunc.execute(user); }
}使用业务上下文
使用时, 在 LogicFunction 中注入相应 业务上下文声明, 在合适的时机调用方法即可.
基本逻辑是, 每个请求会有一个贯穿全局的请求 ID, 注入的是上下文声明的代理, 会根据规则去 Redis 中, 根据请求 ID 和上下文的 Key 等, 查找相关缓存的内容, 如果缓存内容不存在, 则发起调用找业务上下文的实现, 之后将结果放入上下文并返回. 放入上下文的内容, 会自动被清理.
@FunctionImpl(name = "创建商品默认实现")@AllArgsConstructorpublic class CreateItemFuncImpl implements CreateItemFunc {
private final TradeContext tradeContext;
@Override public ItemBO execute(ItemBO item) { BusinessEntity businessEntity = tradeContext.getBusinessEntity(); // 处理业务 ... return itemOptional; }}使用上下文进行数据过滤
dataParams 支持使用用户上下文和业务上下文。
- 获取当前用户id固定为
@currentUserId - 获取业务上下为格式固定为
@context.${key}.${method}.${propertyPath}- 第一部分固定 @context
- 第二部分为业务上下文接口的key, 如 md_TradeContext
- 第三部分为业务上下文的方法,如 getBusinessEntity/businessEntity
- 第四部分为表达式,目前仅支持较为简单方式, 可空
<View title="公司列表"> <Table key="company" model="base_Company" dataCondition="createdBy.id = ? and company.id = ?" dataParams="[@currentUserId, @context.md_TradeContext.getBusinessEntity.companyId]"> <Fields> <Field name="code"/> <Field name="name" /> </Fields> </Table></View>业务上下文缓存问题
业务上下文目前缓存是请求级别的,请求结束之后缓存就自动清理了。 后续会加上session级别和暴露手动清理缓存的接口。