🍇声明式组件
何谓声明式组件?
之前章节介绍的普通组件和条件组件,在写法上需要你自己去定义一个类去继承NodeComponent
或者NodeSwitchComponent
。这样一方面造成了耦合,另一方面由于java是单继承制,所以使用者就无法再去继承自己的类了,在自由度上就少了很多玩法。
声明式组件这一特性允许你自定义的组件不继承任何类和实现任何接口,普通的类也可以依靠注解来完成LiteFlow组件的声明。
# 普通组件的声明
你可以如下去进行一个普通组件的声明:
@LiteflowComponent("a")
@LiteflowCmpDefine
public class ACmp{
@LiteflowMethod(LiteFlowMethodEnum.PROCESS)
public void processAcmp(NodeComponent bindCmp) {
System.out.println("ACmp executed!");
}
@LiteflowMethod(LiteFlowMethodEnum.IS_ACCESS)
public boolean isAcmpAccess(NodeComponent bindCmp){
return true;
}
@LiteflowMethod(LiteFlowMethodEnum.BEFORE_PROCESS)
public void beforeAcmp(String nodeId, Slot slot){
System.out.println("before A");
}
@LiteflowMethod(LiteFlowMethodEnum.AFTER_PROCESS)
public void afterAcmp(String nodeId, Slot slot){
System.out.println("after A");
}
@LiteflowMethod(LiteFlowMethodEnum.ON_SUCCESS)
public void onAcmpSuccess(NodeComponent bindCmp){
System.out.println("Acmp success");
}
@LiteflowMethod(LiteFlowMethodEnum.ON_ERROR)
public void onAcmpError(NodeComponent bindCmp){
System.out.println("Acmp error");
}
@LiteflowMethod(LiteFlowMethodEnum.IS_END)
public boolean isAcmpEnd(NodeComponent bindCmp) {
return false;
}
}
使用者无需继承NodeComponent
了,在你定义的类上,只要类上加上LiteflowCmpDefine
注解,相应的方法上加上LiteflowMethod
注解,即可完成对任意自定义类的组件化工作。
其中LiteFlowMethod
的作用是把你自己的定义的方法映射成组件的方法。除了有示例上的值外,还有其他的映射方法。具体可以看下普通组件章节。
提示
这里注意的是,大部分方法上参数必须传入NodeComponent bindCmp
这个参数,而且必须只有一个参数,否则会报错,而beforeProcess
和afterProcess
还是按照以前的参数定义。这点要注意下,可以查看上面的示例。
以前获取上下文Bean是用this
关键字,现在只需从bindCmp中获取就可以了。
方法的名称可以定义成你想要的任何方式。这个并无限制。
# 选择组件的声明
声明选择组件和普通组件差不多,如下所示:
@Component("e")
@LiteflowSwitchCmpDefine
public class ECmp{
@LiteflowMethod(LiteFlowMethodEnum.PROCESS_SWITCH)
public String processSwitch(NodeComponent bindCmp) throws Exception {
System.out.println("Ecomp executed!");
return "g";
}
}
# 条件组件的声明
@Component("x")
@LiteflowIfCmpDefine
public class XCmp{
@LiteflowMethod(LiteFlowMethodEnum.PROCESS_IF)
public boolean processIf(NodeComponent bindCmp) throws Exception {
//do your biz
return true;
}
}
# 关于实现
声明式组件依靠动态代理来实现,底层用的动态代理框架为ByteBuddy。
所有的动态代理类在注册时类名均做了处理,所以你会看到如下的日志打印
2022-05-16 13:05:56.492 INFO 73054 --- [ main] c.y.l.test.base.cmp.ByteBuddy$a$JLWBAK : [51fbe478db8c4b2cb7ad7519aee0b92d]:[O]start component[ByteBuddy$a$JLWBAK] execution
2022-05-16 13:05:56.496 INFO 73054 --- [ main] c.y.l.test.base.cmp.ByteBuddy$b$JZXUWG : [51fbe478db8c4b2cb7ad7519aee0b92d]:[O]start component[ByteBuddy$b$JZXUWG] execution
2022-05-16 13:05:56.505 INFO 73054 --- [lf-when-thead-0] c.y.l.test.base.cmp.ByteBuddy$c$RWWUCJ : [51fbe478db8c4b2cb7ad7519aee0b92d]:[O]start component[ByteBuddy$c$RWWUCJ] execution
2022-05-16 13:05:56.506 INFO 73054 --- [lf-when-thead-1] c.y.l.test.base.cmp.ByteBuddy$d$RECNPY : [51fbe478db8c4b2cb7ad7519aee0b92d]:[O]start component[ByteBuddy$d$RECNPY] execution
仔细看会发现,所有的动态代理后的类名的格式为:ByteBuddy$你的组件名$随机6位字符串。
所以在看日志时,对于声明式组件而言,你只需要看两个$中间的那个,即为你的组件ID。这点怕有人有疑惑,特地说明一下。