Skip to content
wangwei edited this page Mar 11, 2020 · 3 revisions

特性

  • 规则配置简单,上手容易
  • 屏蔽复杂的数据库,打造一套轻量级的流程引擎
  • 支持基于状态机的工作流
  • 扩展性高,插件丰富

快速上手

1、 项目的pom.xml中引入maven配置

<dependency>
	<groupId>com.hbasesoft.framework</groupId>
	<artifactId>framework-rule-file</artifactId>
	<version>${project.parent.version}</version>
</dependency>

2、编写规则文件,并存放在src/resources/META-INF/rules/目录下

demo.json

{
    "name": "demo", 
    "version": "1.0",
    "children": [
        {
            "component": "Child01Component"
        },
        {
            "component": "Child02Component"
        },
        {
            "component": "Child03Component"
        }
    ]
}

3、流程组建继承com.hbasesoft.framework.rule.core.FlowComponent, 并注入进Spring 容器

Child01Component.java

@Component("Child01Component")
public class Child01Component implements FlowComponent<FlowBean> {

    @Override
    public boolean process(final FlowBean flowBean, final FlowContext flowContext) throws Exception {
        System.out.println("---------Child01Component----------");
        return true;
    }

}

4、调用com.hbasesoft.framework.rule.core.FlowHelper.flowStart(FlowBean, String)方法启动流程

TestFlow.java

@Test
public void flowStart() {
    FlowBean flowBean = new FlowBean();
    FlowHelper.flowStart(flowBean, "demo");

}

插件使用

规则流程自由定义各种插件,framework-rule-core包中已经包含3个插件

  • CodeMatchInterceptor 匹配code的插件,匹配到继续执行,匹配不到跳过
  • ConditionInterceptor 条件判断插件,判断规则使用spring的SpelExpressionParser来实现的
  • ToolsInterceptor 在规则文件中可以使用各种工具类插件

1、使用前需要将插件注入Spring容器

ConfigBean.java

@Configuration
public class ConfigBean {
    /** 注入Code Match插件*/
    @Bean
    public CodeMatchInterceptor codeMatchInterceptor() {
        return new CodeMatchInterceptor("code", "type");
    }
    ....
}

2、在规则文件中使用插件

demo.json

{
    "name": "demo", 
    "version": "1.0",
    "children": [
        {
            "code": "1001"
            "component": "Child01Component"
        },
        {
            "code": "1002",
            "type": "A",
            "component": "Child02Component"
        },
        {
            "component": "Child03Component"
        }
    ]
}

另外框架中还提供了framework-rule-plugin-event、framework-rule-plugin-transaction、framework-rule-plugin-stateMachine插件模块

插件的编写

插件需要实现com.hbasesoft.framework.rule.core.FlowComponentInterceptor 接口

public interface FlowComponentInterceptor extends Comparable<FlowComponentInterceptor> {

     // 流程执行前扩展
    default boolean before(Serializable flowBean, FlowContext flowContext) {
        return true;
    }
    
    // 流程执行后扩展
    default void after(Serializable flowBean, FlowContext flowContext) {
    }
    
    // 流程执行失败的扩展
    default void error(Exception e, Serializable flowBean, FlowContext flowContext) {
    }

}

基于状态机的工作流

1、引入framework-rule-plugin-stateMachine 状态机模块

<dependency>
	<groupId>com.hbasesoft.framework</groupId>
	<artifactId>framework-rule-plugin-stateMachine</artifactId>
	<version>${project.parent.version}</version>
</dependency>

2、在规则文件上增加stateMachine属性的配置,注意stateMachine可以放在整个规则文件的任何节点上,并不一定要至于最顶层。

stateMachine.json

{
    "name": "stateMachine",
    "version": "1.0",
    "begin": "B",      // 状态机启动时会分配一个初使状态  (必填)
    "end": "D,E",     // 当流程Bean状态为D、E两种时,状态机就会停止,不在执行 (必填)
    "error": "E",      // 当流程里面未定义错误状态,统一状态为E (必填)
    "stateMachine": {
        "A": [{          // 当状态为A时    (必填)
                "event": "e1",    // 当进行e1操作时   (必填)
                "end": "C",       // 成功后状态为C     (必填)
                "children": [{
                        "component": "Child02Component",
                        "children": [{
                            "component": "DemoComponent"
                        }]
                    },
                    {
                        "component": "Child01Component",
                        "children": [{
                            "component": "Child03Component"
                        }]
                    }
                ]
            },
            {
                "event": "e2",     // 当进行e2操作时 (必填)
                "end": "D",         // 成功后状态为D     (必填)
                "error": "1001=C, 1002=D, *=E",    // 错误时,对应1001错误码,状态为转向C;1002错误码,状态会转向D,其他错误转向为E      (选填)
                "component": "Child02Component"
            }
        ],
        "B": [{            // 当状态为B时     (必填)
            "event": "e1",     // 可以执行e1操作     (必填)
            "end": "A",       // 成功后状态为A        (必填)
            "component": "Child02Component"
        }], 
        "C": [{        // 当状态为C时     (必填)
            "event": "e1",     //可以执行e1操作     (必填)
            "end": "D",    //  成功后状态为D       (必填)
            "component": "Child01Component"
        }]
    }
}

3、流程bean必须继承 com.hbasesoft.rule.plugin.statemachine.StateMachineFlowBean

StateMachineFlowBean.java

public interface StateMachineFlowBean extends Serializable {
    String getEvent();   //获取操作事件
    String getState();   // 获取当前状态
    void setState(String state);  // 执行完成后设置状态
}

案例:

TestFlow.java

@Test
public void testStateMachineBean() {
    TestStateMachineBean bean = new TestStateMachineBean();
    bean.setEvent("e1");
    System.out.println(JSONObject.toJSONString(bean));
    int result = FlowHelper.flowStart(bean, "stateMachine");
    System.out.println(result);
    System.out.println(JSONObject.toJSONString(bean));
    result = FlowHelper.flowStart(bean, "stateMachine");
    System.out.println(result);
    System.out.println(JSONObject.toJSONString(bean));
    result = FlowHelper.flowStart(bean, "stateMachine");
    System.out.println(result);
    System.out.println(JSONObject.toJSONString(bean));
}

其他说明

  • FlowHelper里面提供多种启动方式,规则可以从文件中读取,也可以执行传入一个json对象,这样就可以把规则存储在数据库中
  • stateMachine并未管理状态的存储,实际的场景下大家根据项目需要自己存储状态
  • FlowComponent 的process方法包含了一个FlowContext 上下文,里面可以获取规则配置里面的各种属性,为了防止过程参数污染flowbean,多个组件件的消息传递可以通过FlowContext的paramMap来实现

1.简介

        Framework属于企业级底层开发框架,集成了log、cache、db、message、rule、tx,每块都以模块形式组织,可以根据项目需要获取模块。我们的初衷是屏蔽项目中各种第三方库之间的版本冲突,打造一套屏蔽底层中间件的全新API,提高项目代码的适配能力。

  • framework-common 定义公用的常量、工具类 采用了spring-boot方式启动, 启动类为Application, 也可以支持web方式启动。
  • framework-log 分布式集成日志模块,详细的记录了每个方法执行的参数、返回结果、执行时间,可以很方便的排查问题或告警,通过远程接口上传服务器(支持直连服务端,也支持通过kafka发送)
  • framework-cache 定义了缓存的获取。 支持注解方式访问缓存, 支持基于Redis的分布式锁
  • framework-db 是简单易用的轻量级DAO(Data Access Object)框架,它集成了Hibernate实体维护和Mybaits SQL分离的两大优势,提供了非入侵式API,可以与Hibernate、SpringJdbc等数据库框架很好的集成
  • framework-job 定时任务,支持quartz、xxl-job、ElasticJob简单封装的定时器,支持分布式、分片等功能
  • framework-message 消息模块,通过简单的api发布和订阅事件, 目前支持kafka、redis、rocketMq
  • framework-rule 规则引擎,基于json的轻量级规则引擎, 支持多种插件及扩展, 例如:基于状态机的工作流引擎
  • framework-tx 分布式事务,支持各种远程接口、同步异步消息。
  • [framework-dependencies] 项目依赖,解决版本包依赖问题
  • [framework-shell] 控制台方式提供命令操作,支持自定义各种命令,做各种小工具使用。
  • [framework-langchain4j] 对langchain4j的补充,支持国内的大模型,让大家更高效的开发AIGC应用。

jdk1.8请使用framework3.X版本,framework4.X已升级至jdk21版本

2.框架的由来

        Hibernate我用了2年半, 13年下半年去中兴软创用了一年SQL服务(软创内部框架), 14年在京东驻场用了2个月的MyBatis,综合了一下这些项目,各有各的优缺点。例如针对复杂业务SQL,hibernate明显能力不足,简单的功能MyBaties也要弄死人,所以一直在思考一个问题有没有一个框架能扬长避短,把大家的优点都发挥出来。 当时在某网站上看了一个帖子介绍了minidao,思路很新颖,拜读了源码。 从此框架之路走起。( 为什么不直接使用minidao,一是这个项目不火、更新节奏也不快,使用风险较大, 二是软创内部使用的都是自己的框架,连spring都没有,hibernate更不可能,jdk都处于1.4、1.5版本,不可能直接使用minidao )

  • 14年7月份左右在软创内部gitlab上发布了第一个版本easydao,主要是结合软创当时的系统框架在其之上封装了一层。
  • 14年10月份在github上发布了easydao 剥离掉软创内部框架依赖,使其可以不依赖软创的框架,可以结合spring和hibernate,或者可以单独使用jdbc来使用。
  • 15年6月开始framework-0.1版本的设计,数据库已经用的很爽了,但是一个项目不仅仅是数据库,还有很多其他东西, 当时针对的是web项目规划了很多模块,类似于现在的web结构, 做了job可以在线管理,消息、rpc、缓存等等功能
  • 16年1月22日正式发布1.0版本
  • 16年7月21日发布2.0版本,web模块和jeecg合并单独组成framework-manager, framework专门解决项目底层问题
  • 17年9月24日发布3.0版本,升级了spring boot版本至2.0, 去掉了dubbox这个rpc框架,引入spring-cloud框架。前端也放弃了jeecg,基于ant-design-pro 实现的一套web框架(目前还未从项目中分离出来,暂未开源)
  • 20年2月4日发布了3.4版本, 增加了framework-tx模块,正式支持分布式事务。
  • 23年人工智能比较火,又增加了framework-langchain4j,专门扩展国内的一些大模型。

3.采用项目

  1. 中兴视通网上营业厅项目V1.0
  2. 咪咕在线客服V1.0
  3. 中国实践教育平台V2.0
  4. 大丰科创园微信项目V1.0
  5. 苏州市总工会微信V1.0
  6. 佛山港华网上营业厅项目V1.0
  7. 苏州港华网上营业厅项目V1.0
  8. 苏州体育局微信活动运营项目V1.0
  9. 苏州市防汛排涝物资管理系统V1.0
  10. 港华集团网上营业厅项目
  11. E网通项目
  12. 港华紫荆微信项目
  13. 港华物联网平台
Clone this wiki locally