public interface DemoOrderService {
/**
* 下单申请
* @param sysParam sysParam
* @param bizParam bizParam
* @return result
*/
"ORDER",funcAction = "APPLY", (apiType = ApiType.SUBMIT, funcBiz =
returnType = OrderApplyResponse.class, errorCodeType = CommonErrorCodeEnum.class)
CommonResult<OrderApplyResponse> apply(ApiReqSysParam sysParam, OrderApplyInfo bizParam);
}
1、Flow用于描述一个完整的业务流程,基于单个业务模型,推进一个或多个业务子环节
2、对于单个业务模型的同一类型业务流程,可以有多个Flow定义,以满足不同业务模式的定制需求
3、Flow包含迁转 (transition) ,组件 (component) 和动作 (action) 三级结构,运作原理如下:每次触发 (operate) 对应于组件的一次action,所有action都成功的component会完结,而所有component都成功的transition将会触发Flow和业务模型的状态迁转。
4、Flow的目标是将复杂流程拆解成多个原子化的业务动作,相互解耦
5、Flow需要结合业务服务/消息/调度等调用入口的触发,才能实现完备的流程推进
6、Flow需要依赖外部调用方提供事务管理机制(通常是业务服务),需要依赖业务模型仓储来控制模型的加载和存储
<flow id="OrderApply" version="001" desc="标准下单流程">
<config>
<model class="xxx.xxx.Order"/>
</config>
<init type="INIT" desc="初始化">
<action operate="INIT.INIT"/>
</init>
<transitions>
<transition from="INIT" to="ITEM_OCCUPIED">
<component type="ITEM" desc="扣减库存">
<action operate="ITEM.OCCUPY"/>
</component>
</transition>
<transition from="ITEM_OCCUPIED" to="DISCOUNT_OCCUPIED">
<component type="DISCOUNT" desc="扣减优惠">
<action operate="DISCOUNT.OCCUPY"/>
</component>
</transition>
<transition from="DISCOUNT_OCCUPIED" to="SUCCESS">
<component type="NOTIFY" desc="下单成功通知">
<action operate="NOTIFY.SELLER"/>
<action operate="NOTIFY.BUYER"/>
</component>
</transition>
</transitions>
</flow>
1、业务组件是某一类业务动作的聚合,面向业务功能设计,不局限于任何一个业务模型
2、业务组件的业务动作,是原子化的最小业务单元,粒度暂无强制要求,但以解耦和复用程度为衡量依据;建议其依赖一个到多个基础设施/业务服务,以模板化的方式提供标准的业务动作实现
3、对于某个业务模型,业务组件通过开放适配器(详见【基础设施-适配】)的方式支持受控定制,或以完全复写的方式实现排他定制(不允许其他业务复用)
4、所有的核心业务逻辑,都应收归到业务组件层及其以下(无流程的简单业务服务除外),包括但不限于:参数校验,业务校验,重入/幂等控制,业务模型变更,合约分组变更,计算规则,外部服务交互等等
5、业务组件需要一套定义规范(xml/annotation等),对其支持的业务动作和业务模型有清晰直观的元数据描述,用以搭建业务流程。元数据包括:业务动作列表和对应的触发点(operate),支持的业务模型列表
public interface BizModelDiscountComponent<T extends BizModel> extends BizModelComponent<T> {
/**
* 占用优惠
* @param context
*/
void occupy(FlowContext context);
/**
* 退回优惠
* @param context
*/
void refund(FlowContext context);
}
<componentTemplate type="DISCOUNT" desc="优惠">
<interface name="xxx.xxx.BizModelDiscountComponent"/>
<bizModelMappings>
<bizModelMapping>
<bizModel class="xxx.xxx.Order"/>
<componentEntry name="orderDiscountComponent"/>
</bizModelMapping>
<bizModelMapping>
<bizModel class="xxx.xxx.RefundOrder"/>
<componentEntry name="refundOrderDiscountComponent"/>
</bizModelMapping>
</bizModelMappings>
<triggerMappings>
<triggerMapping>
<triggerTemplate operatePostfix="OCCUPY"/>
<methodEntry name="occupy"/>
</triggerMapping>
<triggerMapping>
<triggerTemplate operatePostfix="REFUND"/>
<methodEntry name="refund"/>
</triggerMapping>
</triggerMappings>
</componentTemplate>
public abstract class AbstractBizModelDiscountComponent<T extends BizModel> implements BizModelDiscountComponent<T> {
private DiscountApiService discountApiService;
public void occupy(FlowContext context) {
// TODO AdapterConfigInfo根据context从当前合约中获取
T bizModel = (T) context.getBizModel();
getDiscountAdapter().processOnOccupyResult(
bizModel,
discountApiService.occupy(getDiscountAdapter().toOccupyInfo(bizModel, new AdapterConfigInfo()))
);
}
public void refund(FlowContext context) {
// TODO AdapterConfigInfo根据context从当前合约中获取
T bizModel = (T) context.getBizModel();
getDiscountAdapter().processOnRefundResult(
bizModel,
discountApiService.refund(getDiscountAdapter().toRefundInfo(bizModel, new AdapterConfigInfo()))
);
}
"unchecked") (
protected BizModelToDiscountAdapter<T> getDiscountAdapter(){
return (BizModelToDiscountAdapter<T>) FlowInstanceFactory.instanceBizAdapter(
"DISCOUNT", (Class<? extends BizModel>) TypeUtils.getRealClassOfParameterizedType(this));
}
}
public interface NotifyGateway {
/**
* 通知(邮件/短信/站内信)
* @param notifyInfo
* @return
*/
CommonResult<NotifyResponse> notify(NotifyInfo notifyInfo);
}
public abstract class BizModelToDiscountAdapter<U extends BizModel> implements BizModelAdapter<U> {
final public String getType(){
return "DISCOUNT";
}
/**
* 生成扣减申请
* @param bizModel
* @return
*/
abstract public OccupyInfo toOccupyInfo(U bizModel, AdapterConfigInfo configInfo);
/**
* 处理扣减结果
* @param bizModel
* @param result
*/
abstract public void processOnOccupyResult(U bizModel, CommonResult<OccupyResponse> result);
//...
}
public class OrderToDiscountAdapter extends BizModelToDiscountAdapter<Order> {
public List<ConfigDef> getConfigDefs() {
return Lists.newArrayList(
ConfigEnum.DISCOUNT_TYPE,
ConfigEnum.DISCOUNT_TERM
);
}
public OccupyInfo toOccupyInfo(Order bizModel, AdapterConfigInfo configInfo) {
// 解析出客户选择的优惠类型
return new OccupyInfo();
}
public void processOnOccupyResult(Order bizModel, CommonResult<OccupyResponse> result) {
// TODO 根据扣减成功的优惠,重新计算订单金额
}
// ...
}
点击阅读原文了解详情