扩展点
简述
- 扩展点往往被用于我们认为在后续定制开发中会继续扩展的一些功能点,并在开发时留下一段精简的代码逻辑,以便于定制开发团队根据具体的业务场景进行快速的扩展和实现,替换为自己的定制场景中所需要的具体业务逻辑。
- 在使用习惯上,扩展点也分为在线配置声明和实现两部分,在线配置一个扩展点,并可以对该扩展点进行不同的实现,扩展点同声明的不同实现可在定制开发时进行替换。
- 扩展点的常用场景如:价格计算、运费计算、发货状态检查。这些场景都是一些常见的功能模块,但是由于领域不同,或者客户需求不同会有不一样的定制实现,所以适合使用扩展点。
在线配置声明
进入 制品中心->配置->业务域->扩展点,新增扩展点:
- 打开交互控制台(下面简称console)进入到资源仓库,选择一个项目,并且进入项目研发态环境。

-
选择对应的应用版本,通过菜单【配置>业务域】进入业务域列表页面。
-
业务域需要开启在线编辑
-
点击查询进入下一个页面
-

- 查询业务域进入业务域详情页,可看到左侧列出了业务域各类资源,我们可以点击【扩展点】或者【业务上下文】查看资源管理列表。

- 扩展点管理

-
- 创建扩展点

-
- 在创建窗口中填写资源标识、名称、描述、入参配置和出参配置,点击提交即可创建成功扩展点。

-
其中:
-
字段 类型 规则 资源原标识 string 必填,50字以内的大写字母、小写字母或数字组合,必须大写字母开头,编辑时不可修改 名称 string 必填,50个字以内的无限制字符 描述 string 非必填,200个字以内的无限制格式字符 入参类型 dictionary 必填,枚举为:模型、查询模型、模型数组、模型分页、List(集合)、Map(映射)、自定义
默认为:模型入参模型 link 模型 入参模型、常见数据类型、自定义类型全限定名三者之一必填
可选范围为当前应用版本下所有模型常见数据类型 dictionary 入参模型、常见数据类型、自定义类型全限定名三者之一必填 自定义类型全限定类名 string 入参模型、常见数据类型、自定义类型全限定名三者之一必填
必须填写Java类全限定名,
eg:java.lang.String、io.terminus.trantor.base.User
当出/入参类型为映射(Map)时,只能在这里填写参数化类型列表,且必须使用英文字符逗号作为分隔符
eg:java.lang.String, java.lang.Long入参名 string 必填,不限字数的非中文字符 出参模型 link 模型 必填,可选范围为当前应用版本下所有模型 出参类型 dictionary 非必填,不填出参为void。枚举为:模型、模型数组、模型分页、List(集合)、Map(映射)、自定义
默认为:模型 -
- 入参和出参配置可选择多种类型,可自行查看,此外对于在枚举之外的类型,也可以通过选择【自定义】类型自行定义类型信息。


用户可以在先配置编排服务,并通过部署到Maven仓库,并依赖到自己的工程里。
Trantor会按照配置生成一个 Java Interface,如下所示,接口使用 @Extension 注解标明,方法名固定为 execute。
@Extension(name = "ClueBO Extension")public interface ClueExt { void execute(ClueBO clue);}实现
- 扩展点的实现是对上述已声明的 interface 的一个实现类,即 java class
- 扩展点的实现 需要使用
@ExtensionImpl注解,并可以对该实现类进行描述 - 该实现类需要实现扩展点声明中的 execute 方法
- 扩展点的实现应位于
xxx-impl模块工程
具体代码如下,execute 方法中打印了一行日志,代表同步第三方的动作:
@ExtensionImpl(name = "ClueBO extensionImpl")public class ClueExtImpl implements ClueExt { @Override public void execute(ClueBO clue) { log.info("execute ClueExtImpl"); }}示例
示例一
/** * 优惠内容转换 * * @author terminus */@Extension@RouteRuleMatch("promotionCampaign.promotionTemplateTypeDict")public interface DiscountParserExt {
/** * 促销活动优惠视图信息转换 * * @param promotionCampaign 促销活动模型 * @param rules 规则列表 * @return 方案包层优惠模型列表 */ List<CampaignDiscount> execute(PromotionCampaignVO promotionCampaign, List<RuleDO> rules);}/** * @author terminus */@ExtensionImpl(name = "默认优惠模型转换")@RequiredArgsConstructor@RouteRuleValue(isDefault = true)public class DefaultDiscountParserExtImpl implements DiscountParserExt {
private final GroupDiscountParserExt groupDiscountParserExt;
@Override public List<CampaignDiscount> execute(PromotionCampaignVO promotionCampaign, List<RuleDO> rules) { // 初始化促销活动的公共信息 CampaignDiscount campaignDiscount = initCommonProperties(promotionCampaign); campaignDiscount.setRelationRules(rules);
DiscountDO discount = groupDiscountParserExt.execute(promotionCampaign.getCampaignDiscountVO()); campaignDiscount.setDiscount(discount); return Collections.singletonList(campaignDiscount); }}示例二
/** * 根据「客户」查询会员,同人拓展点:用以确认如何通过自然人定位会员 * * @author terminus */@Extension(name = "根据「客户」查询会员拓展点")public interface ListMemberByPersonExt {
/** * 同人方法 * * @param request 入参 * @return 会员列表 */ List<MemberRequestDO> execute(PersonDO request);}/** * 根据「客户」查询会员 * 同人拓展点:用以确认如何通过自然人定位会员 * 默认实现类:根据手机号确定一个人 * * @author terminus */@AllArgsConstructor@ExtensionImplpublic class DefaultListMemberByPersonExtImpl implements ListMemberByPersonExt {
private QueryMemberByPersonIdRetailIdFunc queryMemberByPersonIdRetailIdFunc; @Override public List<MemberRequestDO> execute(PersonDO request) { if (request == null || !StringUtils.hasText(request.getPersonMobile())) { throw new BusinessException(MemberMsg.MEMBER_MOBILE_IS_EMPTY); } //查询member的信息通过personId和业态id MemberRequestDO memberRequestDO=new MemberRequestDO(); memberRequestDO.setPersonId(request.getId());
List<MemberRequestDO> memberRequestDOs = queryMemberByPersonIdRetailIdFunc.execute(memberRequestDO); return memberRequestDOs; }}