前言

首先,感谢大家对上一篇文章[业务可视化-让你的流程图"Run"起来(3.分支选择&跨语言分布式运行节点)]的支持。

下面我以实际业务场景为例,来介绍一下ladybugflow的使用方法。

酒店预定场景(传统写法)

对于下面的酒店预定流程

流程1:

流程2

[流程1]的传统写法1:

定义流程间共享变量;
开始处理(); 查询客户信息处理();
查询酒店信息处理(); 下单处理();
下单成功处理();

假设每个流程用3秒钟,整个流程执行完需要3*5=15秒。

于是衍生出了写法2:

定义流程间共享变量;
开始处理(); 启动 查询客户信息线程处理 A;
启动 查询酒店信息线程处理 B;
等待A,B结束; 下单处理();
下单成功处理();

节省了时间,但各种多线程的实现方式使程序变得复杂,

而且上述写法都把流程图与业务逻辑进行了绑定

也就是流程图中添加,删除节点后,相应的逻辑代码也要修改,测试范围往往是整个流程图的业务逻辑都要进行测试。

酒店预定场景(新写法)

针对上面的问题,我在设计ladybugflow的时候,把流程图和业务逻辑进行了分离

每个业务逻辑对应一个方法,与流程图中的节点进行绑定。

这样修改流程图就不用修改业务逻辑了。

而且流程图可以通过工具拖拽方式生成,还可以在图上查看运行结果。

下面介绍一下ladybugflow中的开发过程

1. 导入依赖

Maven
<!-- https://mvnrepository.com/artifact/io.github.nobuglady/ladybugflow -->
<dependency>
<groupId>io.github.nobuglady</groupId>
<artifactId>ladybugflow</artifactId>
<version>0.0.6</version>
</dependency>
Gradle
// https://mvnrepository.com/artifact/io.github.nobuglady/ladybugflow
implementation 'io.github.nobuglady:ladybugflow:0.0.6'

2. 画流程图,并且生成Json文件

首先把这个文件下载到本地,用浏览器打开

https://github.com/nobuglady/ladybugflow/blob/main/html/network.html

然后点击页面上的[edit]按钮可以画流程图,

画完流程图后,点击[update json]按钮,可以生成流程图对应的json文件。

3. 写业务方法

流程图的每个节点对应下面的一个方法,用@Node注解来关联流程图。

可以用类变量进行参数传递和表示结果,比如下单成功后,设置类变量为"success"。

注:建议用节点ID进行关联,本文为了看起来方便,选择了中文的节点名称进行关联

Flow1.java(注意文件编码为UTF-8)


/**
*
* @author NoBugLady
*
*/
public class Flow1 extends FlowRunner { private String result; public String getResult() {
return result;
} @Node(label = "start")
public void processStart() throws InterruptedException {
System.out.println("启动开始 (模拟业务等待3秒)");
Thread.sleep(3000);
System.out.println("启动结束");
} @Node(label = "查询用户信息")
public void processSearchUser() throws InterruptedException {
System.out.println("查询用户信息开始 (模拟业务等待3秒)");
Thread.sleep(3000);
System.out.println("查询用户信息结束");
} @Node(label = "查询酒店信息")
public void processSearchHotel() throws InterruptedException {
System.out.println("查询酒店信息开始 (模拟业务等待3秒)");
Thread.sleep(3000);
System.out.println("查询酒店信息结束");
} @Node(label = "下单")
public void processOrder() throws InterruptedException {
System.out.println("下单开始 (模拟业务等待3秒)");
Thread.sleep(3000);
System.out.println("下单结束");
} @Node(label = "下单成功")
public void processSuccess() throws InterruptedException {
System.out.println("下单成功开始 (模拟业务等待3秒)");
Thread.sleep(3000);
System.out.println("下单成功结束");
result = "success";
}
}

4. 将流程图的Json文件放入工程

Flow1.json(注意文件编码为UTF-8)

{
"flowId": "your flow id",
"nodes": [
{
"id": "1",
"label": "start"
},
{
"id": "a1a38c2e-0e05-4c68-bd49-f12aea070876",
"label": "查询用户信息",
"readyCheck": 0
},
{
"id": "1a90a997-4390-470a-ae7c-626a725438d2",
"label": "查询酒店信息",
"readyCheck": 0
},
{
"id": "52289e99-363d-4453-8077-ca8bdc6d35bf",
"label": "下单",
"readyCheck": 0
},
{
"id": "16422cbb-ccb0-4fe2-952b-e3ad5c3acbb2",
"label": "下单成功",
"readyCheck": 0
}
],
"edges": [
{
"id": "1",
"from": "1",
"to": "2",
"arrows": "to"
},
{
"id": "b3ad7ab3-8fb6-4527-8cae-6845e03da3e4",
"from": "1",
"to": "a1a38c2e-0e05-4c68-bd49-f12aea070876",
"arrows": "to"
},
{
"id": "001375c7-19e7-436b-bbcd-68e36c8f23b7",
"from": "1",
"to": "1a90a997-4390-470a-ae7c-626a725438d2",
"arrows": "to"
},
{
"id": "dd830043-c7a7-4c71-b91c-10c007b7b19c",
"from": "1a90a997-4390-470a-ae7c-626a725438d2",
"to": "52289e99-363d-4453-8077-ca8bdc6d35bf",
"arrows": "to"
},
{
"id": "21c2c69d-0050-4eca-8283-5a2bcbdc6c37",
"from": "52289e99-363d-4453-8077-ca8bdc6d35bf",
"to": "16422cbb-ccb0-4fe2-952b-e3ad5c3acbb2",
"arrows": "to"
},
{
"id": "19f2f329-8163-4dc6-a353-800df79d18a6",
"from": "a1a38c2e-0e05-4c68-bd49-f12aea070876",
"to": "52289e99-363d-4453-8077-ca8bdc6d35bf",
"arrows": "to"
}
]
}

项目结构如下图所示

Flow1.java和Flow1.json需要放到同一个包下。

5. 启动流程

App1.java(注意文件编码为UTF-8)

/**
*
* @author NoBugLady
*
*/
public class App1 { public static void main(String[] args) { Flow1 testFlow = new Flow1();
testFlow.startFlow(true); System.out.println(testFlow.getResult()); // 不建议每次都调用shutdown,可以在整个App关闭的时候调用一次shutdown
FlowStarter.shutdown(); }
}

6. 查看运行结果

[I]2022/07/27 21:23:12.172  main:ladybugflow.properties in root path not found, use default configuration
[I]2022/07/27 21:23:12.177 main:NodePool started.
[I]2022/07/27 21:23:12.178 main:Ready queue consumer thread started.
[I]2022/07/27 21:23:12.180 main:Complete queue consumer thread started.
[I]2022/07/27 21:23:12.993 [your flow id][38f3567d-77fb-4629-bf7e-68b27633ed68] main:json:
{"flowId":"your flow id","nodes":[{"id":"1","label":"start","readyCheck":0},{"id":"a1a38c2e-0e05-4c68-bd49-f12aea070876","label":"查询用户信息","readyCheck":0},{"id":"1a90a997-4390-470a-ae7c-626a725438d2","label":"查询酒店信息","readyCheck":0},{"id":"52289e99-363d-4453-8077-ca8bdc6d35bf","label":"下单","readyCheck":0},{"id":"16422cbb-ccb0-4fe2-952b-e3ad5c3acbb2","label":"下单成功","readyCheck":0}],"edges":[{"id":"1","from":"1","to":"2","condition":null,"arrows":"to"},{"id":"b3ad7ab3-8fb6-4527-8cae-6845e03da3e4","from":"1","to":"a1a38c2e-0e05-4c68-bd49-f12aea070876","condition":null,"arrows":"to"},{"id":"001375c7-19e7-436b-bbcd-68e36c8f23b7","from":"1","to":"1a90a997-4390-470a-ae7c-626a725438d2","condition":null,"arrows":"to"},{"id":"dd830043-c7a7-4c71-b91c-10c007b7b19c","from":"1a90a997-4390-470a-ae7c-626a725438d2","to":"52289e99-363d-4453-8077-ca8bdc6d35bf","condition":null,"arrows":"to"},{"id":"21c2c69d-0050-4eca-8283-5a2bcbdc6c37","from":"52289e99-363d-4453-8077-ca8bdc6d35bf","to":"16422cbb-ccb0-4fe2-952b-e3ad5c3acbb2","condition":null,"arrows":"to"},{"id":"19f2f329-8163-4dc6-a353-800df79d18a6","from":"a1a38c2e-0e05-4c68-bd49-f12aea070876","to":"52289e99-363d-4453-8077-ca8bdc6d35bf","condition":null,"arrows":"to"}]}
[I]2022/07/27 21:23:12.996 [your flow id][38f3567d-77fb-4629-bf7e-68b27633ed68] pool-1-thread-1:execute node id:1
[I]2022/07/27 21:23:12.996 [your flow id][38f3567d-77fb-4629-bf7e-68b27633ed68] pool-1-thread-1:execute node name:start
启动开始 (模拟业务等待3秒)
启动结束
[I]2022/07/27 21:23:16.003 [your flow id][38f3567d-77fb-4629-bf7e-68b27633ed68] pool-1-thread-1:execute node id:a1a38c2e-0e05-4c68-bd49-f12aea070876
[I]2022/07/27 21:23:16.003 [your flow id][38f3567d-77fb-4629-bf7e-68b27633ed68] pool-1-thread-1:execute node name:查询用户信息
[I]2022/07/27 21:23:16.003 [your flow id][38f3567d-77fb-4629-bf7e-68b27633ed68] pool-1-thread-2:execute node id:1a90a997-4390-470a-ae7c-626a725438d2
查询用户信息开始 (模拟业务等待3秒)
[I]2022/07/27 21:23:16.004 [your flow id][38f3567d-77fb-4629-bf7e-68b27633ed68] pool-1-thread-2:execute node name:查询酒店信息
查询酒店信息开始 (模拟业务等待3秒)
查询酒店信息结束
查询用户信息结束
[I]2022/07/27 21:23:19.008 [your flow id][38f3567d-77fb-4629-bf7e-68b27633ed68] pool-1-thread-1:execute node id:52289e99-363d-4453-8077-ca8bdc6d35bf
[I]2022/07/27 21:23:19.008 [your flow id][38f3567d-77fb-4629-bf7e-68b27633ed68] pool-1-thread-1:execute node name:下单
下单开始 (模拟业务等待3秒)
下单结束
[I]2022/07/27 21:23:22.014 [your flow id][38f3567d-77fb-4629-bf7e-68b27633ed68] pool-1-thread-1:execute node id:16422cbb-ccb0-4fe2-952b-e3ad5c3acbb2
[I]2022/07/27 21:23:22.014 [your flow id][38f3567d-77fb-4629-bf7e-68b27633ed68] pool-1-thread-1:execute node name:下单成功
下单成功开始 (模拟业务等待3秒)
下单成功结束
[I]2022/07/27 21:23:25.025 [your flow id][38f3567d-77fb-4629-bf7e-68b27633ed68] Thread-1:Complete success.
[I]2022/07/27 21:23:25.027 [your flow id][38f3567d-77fb-4629-bf7e-68b27633ed68] Thread-1:json:
{"nodes":[{"id": "1","label": "start" ,"color": "#36AE7C"},{"id": "a1a38c2e-0e05-4c68-bd49-f12aea070876","label": "查询用户信息" ,"color": "#36AE7C"},{"id": "1a90a997-4390-470a-ae7c-626a725438d2","label": "查询酒店信息" ,"color": "#36AE7C"},{"id": "52289e99-363d-4453-8077-ca8bdc6d35bf","label": "下单" ,"color": "#36AE7C"},{"id": "16422cbb-ccb0-4fe2-952b-e3ad5c3acbb2","label": "下单成功" ,"color": "#36AE7C"}],"edges":[{"id": "1","from": "1","to": "2","arrows": "to"},{"id": "b3ad7ab3-8fb6-4527-8cae-6845e03da3e4","from": "1","to": "a1a38c2e-0e05-4c68-bd49-f12aea070876","arrows": "to"},{"id": "001375c7-19e7-436b-bbcd-68e36c8f23b7","from": "1","to": "1a90a997-4390-470a-ae7c-626a725438d2","arrows": "to"},{"id": "dd830043-c7a7-4c71-b91c-10c007b7b19c","from": "1a90a997-4390-470a-ae7c-626a725438d2","to": "52289e99-363d-4453-8077-ca8bdc6d35bf","arrows": "to"},{"id": "21c2c69d-0050-4eca-8283-5a2bcbdc6c37","from": "52289e99-363d-4453-8077-ca8bdc6d35bf","to": "16422cbb-ccb0-4fe2-952b-e3ad5c3acbb2","arrows": "to"},{"id": "19f2f329-8163-4dc6-a353-800df79d18a6","from": "a1a38c2e-0e05-4c68-bd49-f12aea070876","to": "52289e99-363d-4453-8077-ca8bdc6d35bf","arrows": "to"}]}
success
[I]2022/07/27 21:23:25.028 main:Ready queue thread stoped.
[I]2022/07/27 21:23:25.028 main:Ready queue thread stoped.
[I]2022/07/27 21:23:25.028 main:NodePool stoped.

将流程运行结束的json字符串拷贝到下面,然后点击[show network]按钮,可以显示出流程执行后的状态

绿色:执行成功,红色:执行失败,白色:未执行

带分支处理的酒店预定流程

ladybugflow提供了对流程图的分支处理功能。

可以根据节点的返回结果,执行不同的流程。

比如,上例中,增加【检查订单】节点,如下

检查订单成功,则走酒店预定流程,否则,走失败流程。

针对以上流程,我们对检查订单的两个边设置返回值,如下:

生成的Json文件如下

Flow2.json(注意文件编码为UTF-8)

{
"flowId": "your flow id",
"nodes": [
{
"id": "1",
"label": "start"
},
{
"id": "a1a38c2e-0e05-4c68-bd49-f12aea070876",
"label": "查询用户信息",
"readyCheck": 0
},
{
"id": "1a90a997-4390-470a-ae7c-626a725438d2",
"label": "查询酒店信息",
"readyCheck": 0
},
{
"id": "52289e99-363d-4453-8077-ca8bdc6d35bf",
"label": "下单",
"readyCheck": 0
},
{
"id": "16422cbb-ccb0-4fe2-952b-e3ad5c3acbb2",
"label": "下单成功",
"readyCheck": 0
},
{
"id": "5a1068c1-e365-4a51-b617-8cc093ce5e3d",
"label": "检查订单",
"readyCheck": 0
},
{
"id": "0aa3e9de-4015-4db0-9eda-fd1cd0fbbf10",
"label": "可以预定",
"readyCheck": 0
},
{
"id": "7e841bf6-b422-4c2c-b4ec-d2352e22cc88",
"label": "不可预定",
"readyCheck": 0
},
{
"id": "8fc59321-8b96-4e17-9d8e-0c8f5fe9c45e",
"label": "失败处理",
"readyCheck": 0
}
],
"edges": [
{
"id": "1",
"from": "1",
"to": "2",
"arrows": "to"
},
{
"id": "b3ad7ab3-8fb6-4527-8cae-6845e03da3e4",
"from": "0aa3e9de-4015-4db0-9eda-fd1cd0fbbf10",
"to": "a1a38c2e-0e05-4c68-bd49-f12aea070876",
"arrows": "to"
},
{
"id": "001375c7-19e7-436b-bbcd-68e36c8f23b7",
"from": "5a1068c1-e365-4a51-b617-8cc093ce5e3d",
"to": "0aa3e9de-4015-4db0-9eda-fd1cd0fbbf10",
"condition": "1",
"arrows": "to"
},
{
"id": "dd830043-c7a7-4c71-b91c-10c007b7b19c",
"from": "1a90a997-4390-470a-ae7c-626a725438d2",
"to": "52289e99-363d-4453-8077-ca8bdc6d35bf",
"arrows": "to"
},
{
"id": "21c2c69d-0050-4eca-8283-5a2bcbdc6c37",
"from": "52289e99-363d-4453-8077-ca8bdc6d35bf",
"to": "16422cbb-ccb0-4fe2-952b-e3ad5c3acbb2",
"arrows": "to"
},
{
"id": "19f2f329-8163-4dc6-a353-800df79d18a6",
"from": "a1a38c2e-0e05-4c68-bd49-f12aea070876",
"to": "52289e99-363d-4453-8077-ca8bdc6d35bf",
"arrows": "to"
},
{
"id": "822e5c76-ce59-4962-b5e3-a3dfd905fa05",
"from": "1",
"to": "5a1068c1-e365-4a51-b617-8cc093ce5e3d",
"arrows": "to"
},
{
"id": "36d6e697-b835-4374-9fa7-c1cd24b100e9",
"from": "5a1068c1-e365-4a51-b617-8cc093ce5e3d",
"to": "7e841bf6-b422-4c2c-b4ec-d2352e22cc88",
"condition": "0",
"arrows": "to"
},
{
"id": "d4a03a18-2a24-4bec-9717-a82c8a4a764b",
"from": "0aa3e9de-4015-4db0-9eda-fd1cd0fbbf10",
"to": "1a90a997-4390-470a-ae7c-626a725438d2",
"arrows": "to"
},
{
"id": "673051d5-27f5-4578-8fc2-4f5e7352d5d2",
"from": "7e841bf6-b422-4c2c-b4ec-d2352e22cc88",
"to": "8fc59321-8b96-4e17-9d8e-0c8f5fe9c45e",
"arrows": "to"
}
]
}

业务方法中增加酒店检查节点,这里返回1,走检查成功的流程。

Flow2.java(注意文件编码为UTF-8)

/**
*
* @author NoBugLady
*
*/
public class Flow2 extends FlowRunner { private String result; public String getResult() {
return result;
} @Node(label = "start")
public void processStart() throws InterruptedException {
System.out.println("启动开始 (模拟业务等待3秒)");
Thread.sleep(3000);
System.out.println("启动结束");
} @Node(label = "检查订单")
public int processCheckOrder() throws InterruptedException {
System.out.println("检查订单开始 (模拟业务等待3秒)");
Thread.sleep(3000);
System.out.println("检查订单结束");
return 1;
} @Node(label = "可以预定")
public void processCheckOrderOK() throws InterruptedException {
System.out.println("可以预定开始 (模拟业务等待3秒)");
Thread.sleep(3000);
System.out.println("可以预定结束");
} @Node(label = "不可预订")
public void processCheckOrderNG() throws InterruptedException {
System.out.println("不可预订开始 (模拟业务等待3秒)");
Thread.sleep(3000);
System.out.println("不可预订结束");
} @Node(label = "查询用户信息")
public void processSearchUser() throws InterruptedException {
System.out.println("查询用户信息开始 (模拟业务等待3秒)");
Thread.sleep(3000);
System.out.println("查询用户信息结束");
} @Node(label = "查询酒店信息")
public void processSearchHotel() throws InterruptedException {
System.out.println("查询酒店信息开始 (模拟业务等待3秒)");
Thread.sleep(3000);
System.out.println("查询酒店信息结束");
} @Node(label = "下单")
public void processOrder() throws InterruptedException {
System.out.println("下单开始 (模拟业务等待3秒)");
Thread.sleep(3000);
System.out.println("下单结束");
} @Node(label = "下单成功")
public void processSuccess() throws InterruptedException {
System.out.println("下单成功开始 (模拟业务等待3秒)");
Thread.sleep(3000);
System.out.println("下单成功结束");
result = "success";
} @Node(label = "失败处理")
public void processError() throws InterruptedException {
System.out.println("失败处理开始 (模拟业务等待3秒)");
Thread.sleep(3000);
System.out.println("失败处理结束");
result = "error";
}
}

启动流程

App2.java(注意文件编码为UTF-8)

/**
*
* @author NoBugLady
*
*/
public class App2 { public static void main(String[] args) { Flow2 testFlow = new Flow2();
testFlow.startFlow(true); System.out.println(testFlow.getResult()); // 不建议每次都调用shutdown,可以在整个App关闭的时候调用一次shutdown
FlowStarter.shutdown(); }
}

查看运行结果

[I]2022/07/27 21:29:56.046  main:ladybugflow.properties in root path not found, use default configuration
[I]2022/07/27 21:29:56.052 main:NodePool started.
[I]2022/07/27 21:29:56.052 main:Ready queue consumer thread started.
[I]2022/07/27 21:29:56.054 main:Complete queue consumer thread started.
[I]2022/07/27 21:29:56.927 [your flow id][73a425a8-2f13-42bc-9358-111d10378204] main:json:
{"flowId":"your flow id","nodes":[{"id":"1","label":"start","readyCheck":0},{"id":"a1a38c2e-0e05-4c68-bd49-f12aea070876","label":"查询用户信息","readyCheck":0},{"id":"1a90a997-4390-470a-ae7c-626a725438d2","label":"查询酒店信息","readyCheck":0},{"id":"52289e99-363d-4453-8077-ca8bdc6d35bf","label":"下单","readyCheck":0},{"id":"16422cbb-ccb0-4fe2-952b-e3ad5c3acbb2","label":"下单成功","readyCheck":0},{"id":"5a1068c1-e365-4a51-b617-8cc093ce5e3d","label":"检查订单","readyCheck":0},{"id":"0aa3e9de-4015-4db0-9eda-fd1cd0fbbf10","label":"可以预定","readyCheck":0},{"id":"7e841bf6-b422-4c2c-b4ec-d2352e22cc88","label":"不可预定","readyCheck":0},{"id":"8fc59321-8b96-4e17-9d8e-0c8f5fe9c45e","label":"失败处理","readyCheck":0}],"edges":[{"id":"1","from":"1","to":"2","condition":null,"arrows":"to"},{"id":"b3ad7ab3-8fb6-4527-8cae-6845e03da3e4","from":"0aa3e9de-4015-4db0-9eda-fd1cd0fbbf10","to":"a1a38c2e-0e05-4c68-bd49-f12aea070876","condition":null,"arrows":"to"},{"id":"001375c7-19e7-436b-bbcd-68e36c8f23b7","from":"5a1068c1-e365-4a51-b617-8cc093ce5e3d","to":"0aa3e9de-4015-4db0-9eda-fd1cd0fbbf10","condition":"1","arrows":"to"},{"id":"dd830043-c7a7-4c71-b91c-10c007b7b19c","from":"1a90a997-4390-470a-ae7c-626a725438d2","to":"52289e99-363d-4453-8077-ca8bdc6d35bf","condition":null,"arrows":"to"},{"id":"21c2c69d-0050-4eca-8283-5a2bcbdc6c37","from":"52289e99-363d-4453-8077-ca8bdc6d35bf","to":"16422cbb-ccb0-4fe2-952b-e3ad5c3acbb2","condition":null,"arrows":"to"},{"id":"19f2f329-8163-4dc6-a353-800df79d18a6","from":"a1a38c2e-0e05-4c68-bd49-f12aea070876","to":"52289e99-363d-4453-8077-ca8bdc6d35bf","condition":null,"arrows":"to"},{"id":"822e5c76-ce59-4962-b5e3-a3dfd905fa05","from":"1","to":"5a1068c1-e365-4a51-b617-8cc093ce5e3d","condition":null,"arrows":"to"},{"id":"36d6e697-b835-4374-9fa7-c1cd24b100e9","from":"5a1068c1-e365-4a51-b617-8cc093ce5e3d","to":"7e841bf6-b422-4c2c-b4ec-d2352e22cc88","condition":"0","arrows":"to"},{"id":"d4a03a18-2a24-4bec-9717-a82c8a4a764b","from":"0aa3e9de-4015-4db0-9eda-fd1cd0fbbf10","to":"1a90a997-4390-470a-ae7c-626a725438d2","condition":null,"arrows":"to"},{"id":"673051d5-27f5-4578-8fc2-4f5e7352d5d2","from":"7e841bf6-b422-4c2c-b4ec-d2352e22cc88","to":"8fc59321-8b96-4e17-9d8e-0c8f5fe9c45e","condition":null,"arrows":"to"}]}
[I]2022/07/27 21:29:56.931 [your flow id][73a425a8-2f13-42bc-9358-111d10378204] pool-1-thread-1:execute node id:1
[I]2022/07/27 21:29:56.931 [your flow id][73a425a8-2f13-42bc-9358-111d10378204] pool-1-thread-1:execute node name:start
启动开始 (模拟业务等待3秒)
启动结束
[I]2022/07/27 21:29:59.939 [your flow id][73a425a8-2f13-42bc-9358-111d10378204] pool-1-thread-1:execute node id:5a1068c1-e365-4a51-b617-8cc093ce5e3d
[I]2022/07/27 21:29:59.939 [your flow id][73a425a8-2f13-42bc-9358-111d10378204] pool-1-thread-1:execute node name:检查订单
检查订单开始 (模拟业务等待3秒)
检查订单结束
[I]2022/07/27 21:30:02.942 [your flow id][73a425a8-2f13-42bc-9358-111d10378204] pool-1-thread-1:execute node id:0aa3e9de-4015-4db0-9eda-fd1cd0fbbf10
[I]2022/07/27 21:30:02.942 [your flow id][73a425a8-2f13-42bc-9358-111d10378204] pool-1-thread-1:execute node name:可以预定
可以预定开始 (模拟业务等待3秒)
可以预定结束
[I]2022/07/27 21:30:05.950 [your flow id][73a425a8-2f13-42bc-9358-111d10378204] pool-1-thread-1:execute node id:a1a38c2e-0e05-4c68-bd49-f12aea070876
[I]2022/07/27 21:30:05.950 [your flow id][73a425a8-2f13-42bc-9358-111d10378204] pool-1-thread-1:execute node name:查询用户信息
查询用户信息开始 (模拟业务等待3秒)
[I]2022/07/27 21:30:05.951 [your flow id][73a425a8-2f13-42bc-9358-111d10378204] pool-1-thread-2:execute node id:1a90a997-4390-470a-ae7c-626a725438d2
[I]2022/07/27 21:30:05.951 [your flow id][73a425a8-2f13-42bc-9358-111d10378204] pool-1-thread-2:execute node name:查询酒店信息
查询酒店信息开始 (模拟业务等待3秒)
查询酒店信息结束
查询用户信息结束
[I]2022/07/27 21:30:08.956 [your flow id][73a425a8-2f13-42bc-9358-111d10378204] pool-1-thread-1:execute node id:52289e99-363d-4453-8077-ca8bdc6d35bf
[I]2022/07/27 21:30:08.956 [your flow id][73a425a8-2f13-42bc-9358-111d10378204] pool-1-thread-1:execute node name:下单
下单开始 (模拟业务等待3秒)
下单结束
[I]2022/07/27 21:30:11.960 [your flow id][73a425a8-2f13-42bc-9358-111d10378204] pool-1-thread-1:execute node id:16422cbb-ccb0-4fe2-952b-e3ad5c3acbb2
[I]2022/07/27 21:30:11.960 [your flow id][73a425a8-2f13-42bc-9358-111d10378204] pool-1-thread-1:execute node name:下单成功
下单成功开始 (模拟业务等待3秒)
下单成功结束
[I]2022/07/27 21:30:14.975 [your flow id][73a425a8-2f13-42bc-9358-111d10378204] Thread-1:Complete success.
[I]2022/07/27 21:30:14.977 [your flow id][73a425a8-2f13-42bc-9358-111d10378204] Thread-1:json:
{"nodes":[{"id": "1","label": "start" ,"color": "#36AE7C"},{"id": "a1a38c2e-0e05-4c68-bd49-f12aea070876","label": "查询用户信息" ,"color": "#36AE7C"},{"id": "1a90a997-4390-470a-ae7c-626a725438d2","label": "查询酒店信息" ,"color": "#36AE7C"},{"id": "52289e99-363d-4453-8077-ca8bdc6d35bf","label": "下单" ,"color": "#36AE7C"},{"id": "16422cbb-ccb0-4fe2-952b-e3ad5c3acbb2","label": "下单成功" ,"color": "#36AE7C"},{"id": "5a1068c1-e365-4a51-b617-8cc093ce5e3d","label": "检查订单" ,"color": "#36AE7C"},{"id": "0aa3e9de-4015-4db0-9eda-fd1cd0fbbf10","label": "可以预定" ,"color": "#36AE7C"},{"id": "7e841bf6-b422-4c2c-b4ec-d2352e22cc88","label": "不可预定" ,"color": "#E8F9FD"},{"id": "8fc59321-8b96-4e17-9d8e-0c8f5fe9c45e","label": "失败处理" ,"color": "#E8F9FD"}],"edges":[{"id": "1","from": "1","to": "2","arrows": "to"},{"id": "b3ad7ab3-8fb6-4527-8cae-6845e03da3e4","from": "0aa3e9de-4015-4db0-9eda-fd1cd0fbbf10","to": "a1a38c2e-0e05-4c68-bd49-f12aea070876","arrows": "to"},{"id": "001375c7-19e7-436b-bbcd-68e36c8f23b7","from": "5a1068c1-e365-4a51-b617-8cc093ce5e3d","to": "0aa3e9de-4015-4db0-9eda-fd1cd0fbbf10","arrows": "to"},{"id": "dd830043-c7a7-4c71-b91c-10c007b7b19c","from": "1a90a997-4390-470a-ae7c-626a725438d2","to": "52289e99-363d-4453-8077-ca8bdc6d35bf","arrows": "to"},{"id": "21c2c69d-0050-4eca-8283-5a2bcbdc6c37","from": "52289e99-363d-4453-8077-ca8bdc6d35bf","to": "16422cbb-ccb0-4fe2-952b-e3ad5c3acbb2","arrows": "to"},{"id": "19f2f329-8163-4dc6-a353-800df79d18a6","from": "a1a38c2e-0e05-4c68-bd49-f12aea070876","to": "52289e99-363d-4453-8077-ca8bdc6d35bf","arrows": "to"},{"id": "822e5c76-ce59-4962-b5e3-a3dfd905fa05","from": "1","to": "5a1068c1-e365-4a51-b617-8cc093ce5e3d","arrows": "to"},{"id": "36d6e697-b835-4374-9fa7-c1cd24b100e9","from": "5a1068c1-e365-4a51-b617-8cc093ce5e3d","to": "7e841bf6-b422-4c2c-b4ec-d2352e22cc88","arrows": "to"},{"id": "d4a03a18-2a24-4bec-9717-a82c8a4a764b","from": "0aa3e9de-4015-4db0-9eda-fd1cd0fbbf10","to": "1a90a997-4390-470a-ae7c-626a725438d2","arrows": "to"},{"id": "673051d5-27f5-4578-8fc2-4f5e7352d5d2","from": "7e841bf6-b422-4c2c-b4ec-d2352e22cc88","to": "8fc59321-8b96-4e17-9d8e-0c8f5fe9c45e","arrows": "to"}]}
success
[I]2022/07/27 21:30:14.977 main:Ready queue thread stoped.
[I]2022/07/27 21:30:14.977 main:Ready queue thread stoped.
[I]2022/07/27 21:30:14.977 main:NodePool stoped.

将流程运行结束的json字符串拷贝到下面,然后点击[show network]按钮,可以显示出流程执行后的状态

绿色:执行成功,红色:执行失败,白色:未执行

去除不必要的业务节点

实际使用过程中,并非每个业务节点都需要对应业务代码,

比如上例中【可以预定】和【不可预定】可以没有相应的业务逻辑,空跑一下转到后面的节点即可。

所以,我们可以在业务逻辑中去掉上述节点,如下,去掉了【可以预定】和【不可预定】对应的业务方法。

Flow3.java(注意文件编码为UTF-8)


/**
*
* @author NoBugLady
*
*/
public class Flow3 extends FlowRunner { private String result; public String getResult() {
return result;
} @Node(label = "start")
public void processStart() throws InterruptedException {
System.out.println("启动开始 (模拟业务等待3秒)");
Thread.sleep(3000);
System.out.println("启动结束");
} @Node(label = "检查订单")
public int processCheckOrder() throws InterruptedException {
System.out.println("检查订单开始 (模拟业务等待3秒)");
Thread.sleep(3000);
System.out.println("检查订单结束");
return 1;
} @Node(label = "查询用户信息")
public void processSearchUser() throws InterruptedException {
System.out.println("查询用户信息开始 (模拟业务等待3秒)");
Thread.sleep(3000);
System.out.println("查询用户信息结束");
} @Node(label = "查询酒店信息")
public void processSearchHotel() throws InterruptedException {
System.out.println("查询酒店信息开始 (模拟业务等待3秒)");
Thread.sleep(3000);
System.out.println("查询酒店信息结束");
} @Node(label = "下单")
public void processOrder() throws InterruptedException {
System.out.println("下单开始 (模拟业务等待3秒)");
Thread.sleep(3000);
System.out.println("下单结束");
} @Node(label = "下单成功")
public void processSuccess() throws InterruptedException {
System.out.println("下单成功开始 (模拟业务等待3秒)");
Thread.sleep(3000);
System.out.println("下单成功结束");
result = "success";
} @Node(label = "失败处理")
public void processError() throws InterruptedException {
System.out.println("失败处理开始 (模拟业务等待3秒)");
Thread.sleep(3000);
System.out.println("失败处理结束");
result = "error";
}
}

启动代码和流程配置文件不变

App3.java(注意文件编码为UTF-8)

/**
*
* @author NoBugLady
*
*/
public class App3 { public static void main(String[] args) { Flow3 testFlow = new Flow3();
testFlow.startFlow(true); System.out.println(testFlow.getResult()); // 不建议每次都调用shutdown,可以在整个App关闭的时候调用一次shutdown
FlowStarter.shutdown(); }
}

Flow3.json(注意文件编码为UTF-8)

{
"flowId": "your flow id",
"nodes": [
{
"id": "1",
"label": "start"
},
{
"id": "a1a38c2e-0e05-4c68-bd49-f12aea070876",
"label": "查询用户信息",
"readyCheck": 0
},
{
"id": "1a90a997-4390-470a-ae7c-626a725438d2",
"label": "查询酒店信息",
"readyCheck": 0
},
{
"id": "52289e99-363d-4453-8077-ca8bdc6d35bf",
"label": "下单",
"readyCheck": 0
},
{
"id": "16422cbb-ccb0-4fe2-952b-e3ad5c3acbb2",
"label": "下单成功",
"readyCheck": 0
},
{
"id": "5a1068c1-e365-4a51-b617-8cc093ce5e3d",
"label": "检查订单",
"readyCheck": 0
},
{
"id": "0aa3e9de-4015-4db0-9eda-fd1cd0fbbf10",
"label": "可以预定",
"readyCheck": 0
},
{
"id": "7e841bf6-b422-4c2c-b4ec-d2352e22cc88",
"label": "不可预定",
"readyCheck": 0
},
{
"id": "8fc59321-8b96-4e17-9d8e-0c8f5fe9c45e",
"label": "失败处理",
"readyCheck": 0
}
],
"edges": [
{
"id": "1",
"from": "1",
"to": "2",
"arrows": "to"
},
{
"id": "b3ad7ab3-8fb6-4527-8cae-6845e03da3e4",
"from": "0aa3e9de-4015-4db0-9eda-fd1cd0fbbf10",
"to": "a1a38c2e-0e05-4c68-bd49-f12aea070876",
"arrows": "to"
},
{
"id": "001375c7-19e7-436b-bbcd-68e36c8f23b7",
"from": "5a1068c1-e365-4a51-b617-8cc093ce5e3d",
"to": "0aa3e9de-4015-4db0-9eda-fd1cd0fbbf10",
"condition": "1",
"arrows": "to"
},
{
"id": "dd830043-c7a7-4c71-b91c-10c007b7b19c",
"from": "1a90a997-4390-470a-ae7c-626a725438d2",
"to": "52289e99-363d-4453-8077-ca8bdc6d35bf",
"arrows": "to"
},
{
"id": "21c2c69d-0050-4eca-8283-5a2bcbdc6c37",
"from": "52289e99-363d-4453-8077-ca8bdc6d35bf",
"to": "16422cbb-ccb0-4fe2-952b-e3ad5c3acbb2",
"arrows": "to"
},
{
"id": "19f2f329-8163-4dc6-a353-800df79d18a6",
"from": "a1a38c2e-0e05-4c68-bd49-f12aea070876",
"to": "52289e99-363d-4453-8077-ca8bdc6d35bf",
"arrows": "to"
},
{
"id": "822e5c76-ce59-4962-b5e3-a3dfd905fa05",
"from": "1",
"to": "5a1068c1-e365-4a51-b617-8cc093ce5e3d",
"arrows": "to"
},
{
"id": "36d6e697-b835-4374-9fa7-c1cd24b100e9",
"from": "5a1068c1-e365-4a51-b617-8cc093ce5e3d",
"to": "7e841bf6-b422-4c2c-b4ec-d2352e22cc88",
"condition": "0",
"arrows": "to"
},
{
"id": "d4a03a18-2a24-4bec-9717-a82c8a4a764b",
"from": "0aa3e9de-4015-4db0-9eda-fd1cd0fbbf10",
"to": "1a90a997-4390-470a-ae7c-626a725438d2",
"arrows": "to"
},
{
"id": "673051d5-27f5-4578-8fc2-4f5e7352d5d2",
"from": "7e841bf6-b422-4c2c-b4ec-d2352e22cc88",
"to": "8fc59321-8b96-4e17-9d8e-0c8f5fe9c45e",
"arrows": "to"
}
]
}

运行结果

[I]2022/07/27 21:34:29.548  main:ladybugflow.properties in root path not found, use default configuration
[I]2022/07/27 21:34:29.558 main:NodePool started.
[I]2022/07/27 21:34:29.560 main:Ready queue consumer thread started.
[I]2022/07/27 21:34:29.563 main:Complete queue consumer thread started.
[I]2022/07/27 21:34:30.494 [your flow id][970f3310-4ca1-41db-9348-bcc3fe994ce5] main:json:
{"flowId":"your flow id","nodes":[{"id":"1","label":"start","readyCheck":0},{"id":"a1a38c2e-0e05-4c68-bd49-f12aea070876","label":"查询用户信息","readyCheck":0},{"id":"1a90a997-4390-470a-ae7c-626a725438d2","label":"查询酒店信息","readyCheck":0},{"id":"52289e99-363d-4453-8077-ca8bdc6d35bf","label":"下单","readyCheck":0},{"id":"16422cbb-ccb0-4fe2-952b-e3ad5c3acbb2","label":"下单成功","readyCheck":0},{"id":"5a1068c1-e365-4a51-b617-8cc093ce5e3d","label":"检查订单","readyCheck":0},{"id":"0aa3e9de-4015-4db0-9eda-fd1cd0fbbf10","label":"可以预定","readyCheck":0},{"id":"7e841bf6-b422-4c2c-b4ec-d2352e22cc88","label":"不可预定","readyCheck":0},{"id":"8fc59321-8b96-4e17-9d8e-0c8f5fe9c45e","label":"失败处理","readyCheck":0}],"edges":[{"id":"1","from":"1","to":"2","condition":null,"arrows":"to"},{"id":"b3ad7ab3-8fb6-4527-8cae-6845e03da3e4","from":"0aa3e9de-4015-4db0-9eda-fd1cd0fbbf10","to":"a1a38c2e-0e05-4c68-bd49-f12aea070876","condition":null,"arrows":"to"},{"id":"001375c7-19e7-436b-bbcd-68e36c8f23b7","from":"5a1068c1-e365-4a51-b617-8cc093ce5e3d","to":"0aa3e9de-4015-4db0-9eda-fd1cd0fbbf10","condition":"1","arrows":"to"},{"id":"dd830043-c7a7-4c71-b91c-10c007b7b19c","from":"1a90a997-4390-470a-ae7c-626a725438d2","to":"52289e99-363d-4453-8077-ca8bdc6d35bf","condition":null,"arrows":"to"},{"id":"21c2c69d-0050-4eca-8283-5a2bcbdc6c37","from":"52289e99-363d-4453-8077-ca8bdc6d35bf","to":"16422cbb-ccb0-4fe2-952b-e3ad5c3acbb2","condition":null,"arrows":"to"},{"id":"19f2f329-8163-4dc6-a353-800df79d18a6","from":"a1a38c2e-0e05-4c68-bd49-f12aea070876","to":"52289e99-363d-4453-8077-ca8bdc6d35bf","condition":null,"arrows":"to"},{"id":"822e5c76-ce59-4962-b5e3-a3dfd905fa05","from":"1","to":"5a1068c1-e365-4a51-b617-8cc093ce5e3d","condition":null,"arrows":"to"},{"id":"36d6e697-b835-4374-9fa7-c1cd24b100e9","from":"5a1068c1-e365-4a51-b617-8cc093ce5e3d","to":"7e841bf6-b422-4c2c-b4ec-d2352e22cc88","condition":"0","arrows":"to"},{"id":"d4a03a18-2a24-4bec-9717-a82c8a4a764b","from":"0aa3e9de-4015-4db0-9eda-fd1cd0fbbf10","to":"1a90a997-4390-470a-ae7c-626a725438d2","condition":null,"arrows":"to"},{"id":"673051d5-27f5-4578-8fc2-4f5e7352d5d2","from":"7e841bf6-b422-4c2c-b4ec-d2352e22cc88","to":"8fc59321-8b96-4e17-9d8e-0c8f5fe9c45e","condition":null,"arrows":"to"}]}
[I]2022/07/27 21:34:30.497 [your flow id][970f3310-4ca1-41db-9348-bcc3fe994ce5] pool-1-thread-1:execute node id:1
[I]2022/07/27 21:34:30.498 [your flow id][970f3310-4ca1-41db-9348-bcc3fe994ce5] pool-1-thread-1:execute node name:start
启动开始 (模拟业务等待3秒)
启动结束
[I]2022/07/27 21:34:33.502 [your flow id][970f3310-4ca1-41db-9348-bcc3fe994ce5] pool-1-thread-1:execute node id:5a1068c1-e365-4a51-b617-8cc093ce5e3d
[I]2022/07/27 21:34:33.503 [your flow id][970f3310-4ca1-41db-9348-bcc3fe994ce5] pool-1-thread-1:execute node name:检查订单
检查订单开始 (模拟业务等待3秒)
检查订单结束
[I]2022/07/27 21:34:36.518 [your flow id][970f3310-4ca1-41db-9348-bcc3fe994ce5] pool-1-thread-1:execute node id:0aa3e9de-4015-4db0-9eda-fd1cd0fbbf10
[I]2022/07/27 21:34:36.518 [your flow id][970f3310-4ca1-41db-9348-bcc3fe994ce5] pool-1-thread-1:execute node name:可以预定
[I]2022/07/27 21:34:36.519 [your flow id][970f3310-4ca1-41db-9348-bcc3fe994ce5] pool-1-thread-1:execute node id:a1a38c2e-0e05-4c68-bd49-f12aea070876
[I]2022/07/27 21:34:36.519 [your flow id][970f3310-4ca1-41db-9348-bcc3fe994ce5] pool-1-thread-1:execute node name:查询用户信息
查询用户信息开始 (模拟业务等待3秒)
[I]2022/07/27 21:34:36.519 [your flow id][970f3310-4ca1-41db-9348-bcc3fe994ce5] pool-1-thread-2:execute node id:1a90a997-4390-470a-ae7c-626a725438d2
[I]2022/07/27 21:34:36.519 [your flow id][970f3310-4ca1-41db-9348-bcc3fe994ce5] pool-1-thread-2:execute node name:查询酒店信息
查询酒店信息开始 (模拟业务等待3秒)
查询用户信息结束
查询酒店信息结束
[I]2022/07/27 21:34:39.522 [your flow id][970f3310-4ca1-41db-9348-bcc3fe994ce5] pool-1-thread-2:execute node id:52289e99-363d-4453-8077-ca8bdc6d35bf
[I]2022/07/27 21:34:39.522 [your flow id][970f3310-4ca1-41db-9348-bcc3fe994ce5] pool-1-thread-2:execute node name:下单
下单开始 (模拟业务等待3秒)
下单结束
[I]2022/07/27 21:34:42.529 [your flow id][970f3310-4ca1-41db-9348-bcc3fe994ce5] pool-1-thread-2:execute node id:16422cbb-ccb0-4fe2-952b-e3ad5c3acbb2
[I]2022/07/27 21:34:42.529 [your flow id][970f3310-4ca1-41db-9348-bcc3fe994ce5] pool-1-thread-2:execute node name:下单成功
下单成功开始 (模拟业务等待3秒)
下单成功结束
[I]2022/07/27 21:34:45.530 [your flow id][970f3310-4ca1-41db-9348-bcc3fe994ce5] Thread-1:Complete success.
[I]2022/07/27 21:34:45.532 [your flow id][970f3310-4ca1-41db-9348-bcc3fe994ce5] Thread-1:json:
{"nodes":[{"id": "1","label": "start" ,"color": "#36AE7C"},{"id": "a1a38c2e-0e05-4c68-bd49-f12aea070876","label": "查询用户信息" ,"color": "#36AE7C"},{"id": "1a90a997-4390-470a-ae7c-626a725438d2","label": "查询酒店信息" ,"color": "#36AE7C"},{"id": "52289e99-363d-4453-8077-ca8bdc6d35bf","label": "下单" ,"color": "#36AE7C"},{"id": "16422cbb-ccb0-4fe2-952b-e3ad5c3acbb2","label": "下单成功" ,"color": "#36AE7C"},{"id": "5a1068c1-e365-4a51-b617-8cc093ce5e3d","label": "检查订单" ,"color": "#36AE7C"},{"id": "0aa3e9de-4015-4db0-9eda-fd1cd0fbbf10","label": "可以预定" ,"color": "#36AE7C"},{"id": "7e841bf6-b422-4c2c-b4ec-d2352e22cc88","label": "不可预定" ,"color": "#E8F9FD"},{"id": "8fc59321-8b96-4e17-9d8e-0c8f5fe9c45e","label": "失败处理" ,"color": "#E8F9FD"}],"edges":[{"id": "1","from": "1","to": "2","arrows": "to"},{"id": "b3ad7ab3-8fb6-4527-8cae-6845e03da3e4","from": "0aa3e9de-4015-4db0-9eda-fd1cd0fbbf10","to": "a1a38c2e-0e05-4c68-bd49-f12aea070876","arrows": "to"},{"id": "001375c7-19e7-436b-bbcd-68e36c8f23b7","from": "5a1068c1-e365-4a51-b617-8cc093ce5e3d","to": "0aa3e9de-4015-4db0-9eda-fd1cd0fbbf10","arrows": "to"},{"id": "dd830043-c7a7-4c71-b91c-10c007b7b19c","from": "1a90a997-4390-470a-ae7c-626a725438d2","to": "52289e99-363d-4453-8077-ca8bdc6d35bf","arrows": "to"},{"id": "21c2c69d-0050-4eca-8283-5a2bcbdc6c37","from": "52289e99-363d-4453-8077-ca8bdc6d35bf","to": "16422cbb-ccb0-4fe2-952b-e3ad5c3acbb2","arrows": "to"},{"id": "19f2f329-8163-4dc6-a353-800df79d18a6","from": "a1a38c2e-0e05-4c68-bd49-f12aea070876","to": "52289e99-363d-4453-8077-ca8bdc6d35bf","arrows": "to"},{"id": "822e5c76-ce59-4962-b5e3-a3dfd905fa05","from": "1","to": "5a1068c1-e365-4a51-b617-8cc093ce5e3d","arrows": "to"},{"id": "36d6e697-b835-4374-9fa7-c1cd24b100e9","from": "5a1068c1-e365-4a51-b617-8cc093ce5e3d","to": "7e841bf6-b422-4c2c-b4ec-d2352e22cc88","arrows": "to"},{"id": "d4a03a18-2a24-4bec-9717-a82c8a4a764b","from": "0aa3e9de-4015-4db0-9eda-fd1cd0fbbf10","to": "1a90a997-4390-470a-ae7c-626a725438d2","arrows": "to"},{"id": "673051d5-27f5-4578-8fc2-4f5e7352d5d2","from": "7e841bf6-b422-4c2c-b4ec-d2352e22cc88","to": "8fc59321-8b96-4e17-9d8e-0c8f5fe9c45e","arrows": "to"}]}
success
[I]2022/07/27 21:34:45.532 main:Ready queue thread stoped.
[I]2022/07/27 21:34:45.532 main:Ready queue thread stoped.
[I]2022/07/27 21:34:45.533 main:NodePool stoped.

将流程运行结束的json字符串拷贝到下面,然后点击[show network]按钮,可以显示出流程执行后的状态

绿色:执行成功,红色:执行失败,白色:未执行

感谢您读文章到这里。

最后

设计资料和详细的使用方法可以参照上一篇文章:https://www.cnblogs.com/nobuglady/p/16474433.html

源码:https://github.com/nobuglady/ladybugflow

运行例源码:https://github.com/nobuglady/ladybugflow-demo

业务可视化-让你的流程图"Run"起来(4.实际业务场景测试)的更多相关文章

  1. 业务可视化-让你的流程图"Run"起来(2.问题与改进)

    前言 首先,感谢大家对上一篇文章[业务可视化-让你的流程图"Run"起来]的支持. 分享一下近期我对这个项目的一些改进. 问题&改进 问题1: 流程运行开始后,异步执行,无 ...

  2. 业务可视化-让你的流程图"Run"起来(3.分支选择&跨语言分布式运行节点)

    前言 首先,感谢大家对上一篇文章[业务可视化-让你的流程图"Run"起来(2.问题与改进)]的支持. 分享一下近期我对这个项目的一些改进. 1. 增加了分支选择工程,可以根据节点的 ...

  3. 业务可视化-让你的流程图"Run"起来(6.定时任务&Spring-Batch的集成)

    前言 首先,感谢大家对上一篇文章[业务可视化-让你的流程图"Run"起来(5.SpringBoot集成&微服务编排)]的支持. 分享一下近期我对这个项目的一些改进. 在项目 ...

  4. 业务可视化-让你的流程图"Run"起来

    前言 最近在研究业务可视化的问题,在日常的工作中,流程图和代码往往是分开管理的. 一个被维护多次的系统,到最后流程图和代码是否匹配这个都很难说. 于是一直有一个想法,让程序直接读流程图,根据流程图的配 ...

  5. 业务流程可视化-让你的流程图"Run"起来(7.运行状态持久化&轻量工作流支持)

    前言 感谢大家阅读本项目系列文章和对项目的支持.分享一下我对这个项目的新的改进. 之前项目做到了流程设计可视化和流程运行结果可视化. 本期发布的版本中实现了中间的运行过程的实时可视化,和流程状态持久化 ...

  6. 参照企业微信审批业务,在Winform开发框架中工作流模块的实现业务审批

    目前微信的企业号已经切换到企业微信里面,这个是一个APP程序,提供了很丰富的企业应用,其中包括了业务审批处理,审批业务包括请假.报销.费用.出差等很多个审批场景,在Winform开发框架中工作流模块这 ...

  7. IDMC制造业ERP业务场景测试之一——硅钢片制造业务流程测试

    一.测试地址 硅钢片业务测试数据库地址为:http://www.bonawifi.com,测试数据库名字为SiliconSteelSheet,测试账号:用户名demo ,密码demo 二.业务说明 根 ...

  8. 如何使用VSTS做压力测试

    1 前言 1.1 目的 本文档主要介绍如何在VSTS环境中进行LoadTest测试,给测试人员和初次使用者提供参考. 对该工具进行LoadTest测试的优劣进行简单的分析说明. 1.2 软件版本 本文 ...

  9. 【ARTS】01_37_左耳听风-201900722~201900728

    ARTS: Algrothm: leetcode算法题目 Review: 阅读并且点评一篇英文技术文章 Tip/Techni: 学习一个技术技巧 Share: 分享一篇有观点和思考的技术文章 Algo ...

随机推荐

  1. 在SpringBoot中使用logback优化异常堆栈的输出

    一.背景 在我们在编写程序的过程中,无法保证自己的代码不抛出异常.当我们抛出异常的时候,通常会将整个异常堆栈的信息使用日志记录下来.通常一整个异常堆栈的信息是比较多的,而且存在一些没用的信息.那么我们 ...

  2. netty系列之:netty中常用的字符串编码解码器

    目录 简介 netty中的字符串编码解码器 不同平台的换行符 字符串编码的实现 总结 简介 字符串是我们程序中最常用到的消息格式,也是最简单的消息格式,但是正因为字符串string太过简单,不能附加更 ...

  3. this 去哪?

    this 去哪? 本文写于 2020 年 4 月 26 日 let obj = { foo() { console.log(this) }, } let bar = obj.foo obj.foo() ...

  4. Go基础3:函数、结构体、方法、接口

    目录 1. 函数 1.1 函数返回值 同一种类型返回值 带变量名的返回值 函数中的参数传递 函数变量 1.2 匿名函数--没有函数名字的函数 在定义时调用匿名函数 将匿名函数赋值给变量 匿名函数用作回 ...

  5. 『忘了再学』Shell基础 — 17、预定义变量

    目录 1.预定义变量$? 2.预定义变量$$和$! 我们之前说过,Shell中的变量不是按照变量值的类型来进行分类的,而是按照Linux系统中定义的变量类别来分类的. 预定义变量就是,事先把变量的名称 ...

  6. 对 Python 中 GIL 的一点理解

    GIL(Global Interpreter Lock),全局解释器锁,是 CPython 为了避免在多线程环境下造成 Python 解释器内部数据的不一致而引入的一把锁,让 Python 中的多个线 ...

  7. SpringMVC请求流程源码分析

    一.SpringMVC使用 1.工程创建 创建maven工程. 添加java.resources目录. 引入Spring-webmvc 依赖. <dependency> <group ...

  8. vue跑马灯vue3-marquee

    安装vue3-marquee 如果您使用的是 npm: npm install vue3-marquee@latest --save 如果您使用的是yarn: yarn add vue3-marque ...

  9. 论文解读(SUBLIME)《Towards Unsupervised Deep Graph Structure Learning》

    论文信息 论文标题:Towards Unsupervised Deep Graph Structure Learning论文作者:Yixin Liu, Yu Zheng, Daokun Zhang, ...

  10. KNN算法推理与实现

    Overview K近邻值算法 KNN (K - Nearest Neighbors) 是一种机器学习中的分类算法:K-NN是一种非参数的惰性学习算法.非参数意味着没有对基础数据分布的假设,即模型结构 ...