样例说明
通过本Quickstart Guide,您将完成:
1、一个扩展点的定义
2、业务包对该扩展点的自定义逻辑实现
3、启动Lattice,并完成对该扩展点的调用
环境准备
您需要:
1、用于运行程序的IDE(集成开发环境),比如IntelliJ IDEA 或其类似工具;
2、Java™ Development Kit (JDK),需要JDK 8及以上版本
版本依赖
<dependency>
<groupId>org.hiforce.lattice</groupId>
<artifactId>lattice-model</artifactId>
<version>1.0.8.3</version>
</dependency>
<dependency>
<groupId>org.hiforce.lattice</groupId>
<artifactId>lattice-runtime</artifactId>
<version>1.0.8.3</version>
</dependency>
Step 1:定义 “自定义商品单价” 扩展点
定义一个“自定义子订单商品单价”的扩展点,允许业务能够去实现该扩展点,返回商品的自定义单价。
public interface OrderLinePriceExt extends IBusinessExt {
String EXT_ORDER_LINE_CUSTOM_UNIT_PRICE = "OrderLinePriceExt.EXT_ORDER_LINE_CUSTOM_UNIT_PRICE";
@Extension(
code = EXT_ORDER_LINE_CUSTOM_UNIT_PRICE,
name = "Custom the Item's unit price of OrderLine",
reduceType = ReduceType.FIRST
)
Long getCustomUnitPrice(OrderLine orderLine);
}
扩展点用 @Extension 注解进行标识,并分配一个全局唯一的扩展点编码,同时申明该扩展点的Reduce策略为 FIRST。 (Reduce策略本章大家可以忽略,后面另起文章说明)
Step 2:定义 “子订单价格管理” 能力
@Ability(name = "OrderLine's Price Ability")
public class OrderLinePriceAbility extends BaseLatticeAbility<OrderLinePriceExt> {
public OrderLinePriceAbility(OrderLine bizObject) {
super(bizObject);
}
public Long getCustomUnitPrice(OrderLine orderLine) {
return Optional.ofNullable(reduceExecute(
p -> p.getCustomUnitPrice(orderLine),
Reducers.firstOf(Objects::nonNull)))
.orElse(orderLine.getUnitPrice());
}
@Override
public BlankOrderLinePriceExt getDefaultRealization() {
return new BlankOrderLinePriceExt();
}
}
能力的定义用 @Ability 注解进行标识,同时需要申明当前的能力管理的扩展点集合是 OrderLinePriceExt。 并且,通过 getDefaultRealization() 方法,提供一个默认实现。
能力通过 reduceExecute () 方法尝试去加载 业务 针对 “自定义商品单价” 扩展点的自定义实现逻辑。
Step 3:编写业务自定义实现逻辑
我们定义一个业务A,用 @Business 注解标识,并定义该业务的编码为 "business.a",如下:
@Business(code = "business.a", name = "Business A")
public class BusinessA extends BusinessTemplate {
}
然后,针对业务A,定义它的商品自定义单价为 2000 (单位分)。
@Realization(codes = "business.a")
public class BusinessAExt extends BlankOrderLinePriceExt {
@Override
public Long getCustomUnitPrice(OrderLine orderLine) {
return 2000L;
}
}
业务的自定义实现逻辑用 @Realization 标识,并且 业务编码 是 "business.a"
我们可以用类似的方法,再定义一个业务B,同时业务B对商品单价没有做任何定制,如下:
@Business(code = "business.b", name = "Business B")
public class BusinessB extends BusinessTemplate {
}
@Realization(codes = "business.b")
public class BusinessBExt extends BlankOrderLinePriceExt {
//do nothing.
}
Step 4:启动Lattice,并执行扩展点
public class LatticeQuickStart {
public static void main(String[] args) {
Lattice.getInstance().setSimpleMode(true);
Lattice.getInstance().start();
doBusinessA();
doBusinessB();
}
private static void doBusinessA() {
OrderLine orderLine = new OrderLine();
orderLine.setUnitPrice(1000L);
orderLine.setBizCode("business.a");
OrderLinePriceAbility ability = new OrderLinePriceAbility(orderLine);
Long unitPrice = ability.getCustomUnitPrice(orderLine);
System.out.println("[Business A] unit price: " + unitPrice);
}
private static void doBusinessB() {
OrderLine orderLine = new OrderLine();
orderLine.setUnitPrice(1000L);
orderLine.setBizCode("business.b");
OrderLinePriceAbility ability = new OrderLinePriceAbility(orderLine);
Long unitPrice = ability.getCustomUnitPrice(orderLine);
System.out.println("[Business B] unit price: " + unitPrice);
}
}
我们分别模拟两次业务调用,其中商品默认单价(数据库中商品发布后的默认价格)为 1000L。 因为业务A对商品单价有定制,最终返回值应该是被定制后的 2000L; 而业务B没有做任何定制,所以返回值依然应该是 1000L。 运行org.hiforce.lattice.sample.LatticeQuickStart#main的控制台打印结果如下:
[Business A] unit price: 2000
[Business B] unit price: 1000
样例代码
样例代码可以通过访问: https://github.com/hiforce/lattice-sample/tree/main/lattice-quick-start 获取
2022-11-24 at 下午9:06
毗卢大神好,请教您个问题:在能力实现中,使用模板方法执行具体的扩展点方法,通过动态代理触发callback方法执行,从而往上下文中注入扩展点的方法、参数、编码,我发现在https://github.com/hiforce/lattice/blob/main/lattice-runtime/src/main/java/org/hiforce/lattice/runtime/ability/BaseLatticeAbility.java类的130行和162行重复执行了enrichAbilityInvokeContext这个方法,请问是有什么考究麽?
将162行注释后,执行结果貌似也不受影响。
2022-11-25 at 下午2:15
这个地方是主要有两个原因:
1、用lambda方式,是没有办法直接得到具体入参。那么如果想要做详细的调用日志记录,或者以后用流量录制来做自动化用例时,这个入参信息就获取不到了。通过这种方式可以获取。
2、这个更重要的原因是,Lattice支持RPC方式调用远程扩展点的实现。所有的远程扩展点实现的调用,都是调用的LatticeRemoteInvoker这个接口的 invoke方法,我们需要把实际入参传递过去。 RPC调用可以参考: https://www.ryu.xin/2022/10/01/lattice-rpc-invoke/
3、130行的那个,可以注释掉了。。
2023-03-21 at 下午3:02
我也发现这个了,还在github上提了个issue,没想到大佬早在去年11月份就发现了哈哈