Activiti工作流的详细介绍[通俗易懂]

Activiti工作流的详细介绍[通俗易懂]一、了解工作流1、工作流(Workflow),就是“业务过程的部分或整体在计算机应用环境下的自动化”,它主要解决的是“使在多个参与者之间按照某种预定义的规则传递文档、信息或任务的过程自动进行,从而实现某个预期的业务目标,或者促使此目标的实现。2、工作流管理系统(WorkflowManagementSystem,WfMS)是一个软件系统,它完成工作量的定义和管理,并按照在系统中预先定义好的工作流逻辑进行工作流实例的执行。工作流管理系统不是企业的业务系统,而是为企业的业务系统的运行提供了一个软件的

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

一、了解工作流

1、工作流(Workflow),就是“业务过程的部分或整体在计算机应用环境下的自动化”,它主要解决的是“使在多个参与者之间按照某种预定义的规则传递文档、信息或任务的过程自动进行,从而实现某个预期的业务目标,或者促使此目标的实现。

2、工作流管理系统(Workflow Management System, WfMS)是一个软件系统,它完成工作量的定义和管理,并按照在系统中预先定义好的工作流逻辑进行工作流实例的执行。工作流管理系统不是企业的业务系统,而是为企业的业务系统的运行提供了一个软件的支撑环境。

3、常见的工作流框架有Activity、JBPM、OSWorkFlow、WorkFlow。本系列使用activiti5.13版本。

4、工作流框架底层需要有数据库提供支持,activiti5.13版本,有23张表。JBPM4.4框架有18张表。JBPM底层使用hibernate操作数据库。Activiti框架底层使用的mybatis操作数据库。

二、Activiti介绍

Activiti5是由Alfresco软件在2010年5月17日发布的业务流程管理(BPM)框架,它是覆盖了业务流程管理、工作流、服务协作等领域的一个开源的、灵活的、易扩展的可执行流程语言框架。Activiti基于Apache许可的开源BPM平台,创始人Tom Baeyens是JBoss jBPM的项目架构师,它特色是提供了eclipse插件,开发人员可以通过插件直接绘画出业务流程图。 

 

三、下载与目录结构

官网:https://www.activiti.org/  ,没啥用,打开了也没啥东西。直接在GitHub上下载。

GitHub:https://github.com/Activiti/Activiti  这里下载的时activity-dev

目录结构如下:

Activiti工作流的详细介绍[通俗易懂]

database :提供了建表语句。

docs:该目录包含了三种文档:javadocs、userguide、xsd。

  1. javadocs:API文档,包名按照功能模块划分,org.activiti.engine.*。
  2. userguide:用户手册,包含环境配置、10分钟快速入门以及各个功能模块的使用教程。
  3. xsd:包含BPMN2.0规范的XSD文件以及Activiti扩展的自定义标签XSD。

libs:开发用的jar包和源码包。

wars:提供了两个例子程序。

 

安装activiti流程设计器插件

1、eclipse中安装如下:

1.1、获得插件的安装包

 Activiti工作流的详细介绍[通俗易懂]

1.2、解压安装包,复制到eclipse中的dropins目录中

 Activiti工作流的详细介绍[通俗易懂]

1.3、重启eclipse,勾选save选项

 Activiti工作流的详细介绍[通俗易懂]

IDEA 安装Activiti Designer插件—actiBPM

打开IDEA,按ctrl+alt+S,打开Pluging
 

Activiti工作流的详细介绍[通俗易懂]

安装成功后,创建数据库:

初始化表结构

方式1、使用activiti框架提供的建表语句

在database目录下找到相应数据库的建表语句,执行即可。这里我用的是mysql(可以手动执行,也可用工具)

 Activiti工作流的详细介绍[通俗易懂]

手动执行:

Activiti工作流的详细介绍[通俗易懂]

Activiti工作流的详细介绍[通俗易懂]

Activiti工作流的详细介绍[通俗易懂]

工具的话就不用说了吧

方式2、使用activiti框架的自动建表功能。activiti框架提供了和hibernate类似的自动建表功能。

创建一个java项目,导入jar包,不知道导哪些jar包,可以到war目录解压示例程序。把lib目录中的jar包拷过来即可。当然数据库驱动包时必不可少的。

1、 不使用配置文件(不建议)

复制代码

 @Test
    public void test1(){
        //1.创建一个流程引擎配置对象
        ProcessEngineConfiguration configuration=  ProcessEngineConfiguration.createStandaloneInMemProcessEngineConfiguration();
        //设置数据源
        configuration.setJdbcDriver("com.mysql.jdbc.Driver");
        configuration.setJdbcUrl("jdbc:mysql:///activiti_demo");
        configuration.setJdbcUsername("root");
        configuration.setJdbcPassword("123456");

        //设置自动建表
        configuration.setDatabaseSchema("true");

        //创建一个流程引擎对象,在创建流程引擎对象时会自动建表
        ProcessEngine engine= configuration.buildProcessEngine();
    }

复制代码

2、使用配置文件

 配置文件可以到示例程序的class目录拷贝 activiti-context.xml,修改里面的内容即可。

配置文件

复制代码

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">

    <!--配置流程引擎配置对象-->
    <bean id="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneInMemProcessEngineConfiguration">
        <property name="jdbcDriver"  value="com.mysql.jdbc.Driver"/>
        <property name="jdbcUrl" value="jdbc:mysql:///activiti_demo"/>
        <property name="jdbcUsername" value="root" />
        <property name="jdbcPassword" value="123456" />
        <property name="databaseSchemaUpdate" value="true"/>
    </bean>
</bean>

复制代码

java代码

复制代码

   //使用配置文件
    @Test
    public void test2(){
        //1.创建一个流程引擎配置对象
        String resource="activiti-context.xml";
        String beanName="processEngineConfiguration";
        ProcessEngineConfiguration configuration=  ProcessEngineConfiguration.createProcessEngineConfigurationFromResource(resource,beanName);

        //创建一个流程引擎对象,在创建流程引擎对象时会自动建表
        ProcessEngine engine= configuration.buildProcessEngine();
    }

复制代码

3、使用配置文件(使用默认配置),要求配置文件名称必须为activiti-context.xml或者activiti.cfg.xml,配置的信息必须为

 配置文件如下:

复制代码

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">

    <!--配置流程引擎配置对象-->
    <bean id="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneInMemProcessEngineConfiguration">
        <property name="jdbcDriver"  value="com.mysql.jdbc.Driver"/>
        <property name="jdbcUrl" value="jdbc:mysql:///activiti_demo"/>
        <property name="jdbcUsername" value="root" />
        <property name="jdbcPassword" value="123456" />
        <property name="databaseSchemaUpdate" value="true"/>
    </bean>
    <!--配置工厂,用于创建流程引擎 id必须为processEngine-->
    <bean id="processEngine" class="org.activiti.spring.ProcessEngineFactoryBean">
        <property name="processEngineConfiguration" ref="processEngineConfiguration" />
    </bean>
</bean>

复制代码

java代码

    //使用默认配置文件
    @Test
    public void test3(){
        ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();
    }

了解25张表

Activiti的后台是有数据库的支持,所有的表都以ACT_开头。 第二部分是表示表的用途的两个字母标识。 用途也和服务的API对应。

  1.  ACT_RE_*: ‘RE’表示repository。 这个前缀的表包含了流程定义和流程静态资源 (图片,规则,等等)。
  2.  ACT_RU_*: ‘RU’表示runtime。 这些运行时的表,包含流程实例,任务,变量,异步任务等运行中的数据。 Activiti只在流程实例执行过程中保存这些数据, 在流程结束时就会删除这些记录。 这样运行时表可以一直很小速度很快。
  3. ACT_ID_*: ‘ID’表示identity。 这些表包含身份信息,比如用户,组等等。
  4. ACT_HI_*: ‘HI’表示history。 这些表包含历史数据,比如历史流程实例, 变量,任务等等。
  5. ACT_GE_*: 通用数据, 用于不同场景下。

Activiti工作流的详细介绍[通俗易懂]

使用框架提供的API完成流程操作

可以在项目中加入log4j,将框架执行的sql输出到控制台,log4j提供的日志级别:Fatal error warn info debug trace

部署流程定义

需要先画好流程图

复制代码

/**
     * 部署流程定义(操作数据表:act_re_deployment、act_re_procdef、act_ge_bytearray)
     */
    @Test
    public void test4() {
        // 获得一个部署构建器对象,用于加载流程定义文件(test1.bpmn,test.png)完成流程定义的部署
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        DeploymentBuilder builder= processEngine.getRepositoryService().createDeployment();
        // 加载流程定义文件
        builder.addClasspathResource("process/test1.bpmn");
        builder.addClasspathResource("process/test1.png");
        // 部署流程定义
        Deployment deployment = builder.deploy();
        System.out.println(deployment.getId());
    }

复制代码

查询流程定义列表

复制代码

    @Test
    public void test5() {
        //流程定义查询对象,用于查询act_re_procdef表
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        ProcessDefinitionQuery query = processEngine.getRepositoryService().createProcessDefinitionQuery();
        //添加查询条件
        query.processDefinitionKey("bxlc");
        query.orderByDeploymentId().desc();
        //分页查询
        query.listPage(0, 10);
        List<ProcessDefinition> list = query.list();
        for (ProcessDefinition item : list) {
            System.out.print(item.getId());
        }
    }

复制代码

 

启动流程实例

什么是流程实例?根据一个流程定义具体的一次执行过程就是一个流程实例,一个流程定义对应多个流程实例(一对多关系)

 为了演示:在流程图中指定办理人是谁,现在是写死的,表示只能张三能提交请假申请。后面会讲解如何动态指定。

Activiti工作流的详细介绍[通俗易懂]

复制代码

    //根据流程定义的Id启动一个流程实例(操作ACT_RU_EXECUTION、ACT_RU_TASK、ACT_HI_PROCINST、ACT_HI_ACTINST、ACT_HI_TASKINST、ACT_RU_IDENTITYLINK、ACT_HI_IDENTITYLINK表)
    @Test
    public void test6() {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        String processDefinitionId="qjlc:1:104";
        ProcessInstance processInstance = processEngine.getRuntimeService().startProcessInstanceById(processDefinitionId);
        System.out.print(processInstance.getId());//201
    }

复制代码

查询个人任务列表

复制代码

    @Test
    public void test7() {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        TaskQuery query = processEngine.getTaskService().createTaskQuery();
        query.taskAssignee("张三");
        List<Task> list = query.list();
        for (Task item : list) {
            System.out.print(item.getId()+"==="+item.getName());//204===提交请假申请
        }
    }

复制代码

办理任务

复制代码

    //办理任务(主要操作ACT_RU_EXECUTION、ACT_RU_TASK表)
    @Test
    public void test8() {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        processEngine.getTaskService().complete("204");
    }

复制代码

办理任务后,流程就走到了下一个节点,再次查询张三个人任务列表就查不到了,此时用李四去查就可以了。

使用Activiti框架的API操作流程

复制代码

/**
 * 使用Activiti框架的API操作流程
*/
public class ActivitiAPITest {
    ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
    /**
     * 部署流程定义 方式一:读取单个的流程定义文件 方式二:读取zip压缩文件
     */
    @Test
    public void test1() {
        DeploymentBuilder deploymentBuilder = processEngine.getRepositoryService().createDeployment();

        // 方式一:读取单个的流程定义文件
        deploymentBuilder.addClasspathResource("test1.bpmn");
        deploymentBuilder.addClasspathResource("test1.png"); 
        Deployment deployment = deploymentBuilder.deploy();

        // 方式二:读取zip压缩文件
        /*ZipInputStream zipInputStream = new ZipInputStream(this.getClass().getClassLoader().getResourceAsStream("process.zip"));
        deploymentBuilder.addZipInputStream(zipInputStream);
        deploymentBuilder.name("请假流程部署");
        Deployment deployment = deploymentBuilder.deploy();*/
    }

    /**
     * 查询部署列表
     */
    @Test
    public void test2() {
        // 部署查询对象,查询表act_re_deployment
        DeploymentQuery query = processEngine.getRepositoryService().createDeploymentQuery();
        List<Deployment> list = query.list();
        for (Deployment deployment : list) {
            String id = deployment.getId();
            System.out.println(id);
        }
    }

    /**
     * 查询流程定义列表
     */
    @Test
    public void test3() {
        // 流程定义查询对象,查询表act_re_procdef
        ProcessDefinitionQuery query = processEngine.getRepositoryService().createProcessDefinitionQuery();
        List<ProcessDefinition> list = query.list();
        for (ProcessDefinition pd : list) {
            System.out.println(pd.getName() + "" + pd.getId());
        }
    }

    /**
     * 删除部署信息
     */
    @Test
    public void test4() {
        String deploymentId = "1001";
        // processEngine.getRepositoryService().deleteDeployment(deploymentId);
        processEngine.getRepositoryService().deleteDeployment(deploymentId,true);
    }

    /**
     * 删除流程定义(通过删除部署信息达到删除流程定义的目的)
     */
    @Test
    public void test5() {
        String deploymentId = "1401";
        // processEngine.getRepositoryService().deleteDeployment(deploymentId);
        processEngine.getRepositoryService().deleteDeployment(deploymentId,
                true);
    }

    /**
     * 查询一次部署对应的流程定义文件名称和对应的输入流(bpmn png)
     * 
     * @throws Exception
     */
    @Test
    public void test6() throws Exception {
        String deploymentId = "101";
        List<String> names = processEngine.getRepositoryService()
                .getDeploymentResourceNames(deploymentId);
        for (String name : names) {
            System.out.println(name);
            InputStream in = processEngine.getRepositoryService()
                    .getResourceAsStream(deploymentId, name);
            // 将文件保存到本地磁盘
            /*
             * OutputStream out = new FileOutputStream(new File("d:\\" + name));
             * byte[] b = new byte[1024]; int len = 0; while((len =
             * in.read(b))!=-1) { out.write(b, 0, len); } out.close();
             */
            FileUtils.copyInputStreamToFile(in, new File("d:\\" + name));
            in.close();
        }
    }

    /**
     * 获得png文件的输入流
     * 
     * @throws Exception
     */
    @Test
    public void test7() throws Exception {
        String processDefinitionId = "qjlc:9:1204";
        InputStream pngInputStream = processEngine.getRepositoryService()
                .getProcessDiagram(processDefinitionId);
        FileUtils.copyInputStreamToFile(pngInputStream, new File("d:\\my.png"));
    }

    /**
     * 启动流程实例 方式一:根据流程定义的id启动 方式二:根据流程定义的key启动(自动选择最新版本的流程定义启动流程实例)
     */
    @Test
    public void test8() {
        /*
         * String processDefinitionId = "qjlc:9:1204"; ProcessInstance
         * processInstance =
         * processEngine.getRuntimeService().startProcessInstanceById
         * (processDefinitionId ); System.out.println(processInstance.getId());
         */

        String processDefinitionKey = "qjlc";
        ProcessInstance processInstance = processEngine.getRuntimeService()
                .startProcessInstanceByKey(processDefinitionKey);
        System.out.println(processInstance.getId());
    }

    /**
     * 查询流程实例列表,查询act_ru_execution表
     */
    @Test
    public void test9(){
        //流程实例查询对象,查询act_ru_execution表
        ProcessInstanceQuery query = processEngine.getRuntimeService().createProcessInstanceQuery();
        query.processDefinitionKey("qjlc");
        query.orderByProcessInstanceId().desc();
        query.listPage(0, 2);
        List<ProcessInstance> list = query.list();
        for (ProcessInstance pi : list) {
            System.out.println(pi.getId() + " " + pi.getActivityId());
        }
    }

    /**
     * 结束流程实例,操作的表act_ru_execution act_ru_task
     */
    @Test
    public void test10(){
        String processInstanceId = "1601";
        processEngine.getRuntimeService().deleteProcessInstance(processInstanceId , "我愿意");
    }

    /**
     * 查询任务列表
     */
    @Test
    public void test11(){
        //任务查询对象,查询act_ru_task表
        TaskQuery query = processEngine.getTaskService().createTaskQuery();
        String assignee = "李四";
        query.taskAssignee(assignee);
        query.orderByTaskCreateTime().desc();
        List<Task> list = query.list();
        for (Task task : list) {
            System.out.println(task.getId());
        }
    }

    /**
     * 办理任务
     */
    @Test
    public void test12(){
        String taskId = "2902";
        processEngine.getTaskService().complete(taskId);
    }

    /**
     * 直接将流程向下执行一步
     */
    @Test
    public void test13(){
        String executionId = "2701";//流程实例id
        processEngine.getRuntimeService().signal(executionId);
    }
    
    /**
     * 查询最新版本的流程定义列表
     */
    @Test
    public void test14(){
        ProcessDefinitionQuery query = processEngine.getRepositoryService().createProcessDefinitionQuery();
        query.orderByProcessDefinitionVersion().asc();
        List<ProcessDefinition> list = query.list();
        Map<String, ProcessDefinition> map = new HashMap<String, ProcessDefinition>();
        for (ProcessDefinition pd : list) {
            map.put(pd.getKey(), pd);
        }
        ArrayList<ProcessDefinition> lastList = new ArrayList<>(map.values());
        for (ProcessDefinition processDefinition : lastList) {
            System.out.println(processDefinition.getName() + "  "+ processDefinition.getVersion() );
        }
    }
}

复制代码

Activiti框架提供的Service对象

  1. RepositoryService—-操作静态的资源(流程定义,bpmn、png)
  2. RuntimeService—–操作流程实例(启动流程实例、查询流程实例、结束流程实例)
  3. TaskService—–操作任务(查询任务、办理任务)
  4. HistoryService—-操作历史数据

Activiti框架提供的对象(和表有对应关系)

  • Deployment—–act_re_deployment
  • ProcessDefinition—-act_re_procdef
  • ProcessInstance—–act_ru_execution
  • Task—–act_ru_task

使用网页版流程设计器

1、将activiti-explorer.war复制到tomcat中

2、启动tomcat,访问http://lcoalhost:8080/activiti-explorer

3、使用kermit/kermit登录

4、Activiti工作流的详细介绍[通俗易懂]

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/185453.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • AWS(EC2)助我实现项目管理应用上云

    AWS(EC2)助我实现项目管理应用上云AWS(EC2)助我实现项目管理应用上云

  • navicat 15 激活码 3月最新注册码

    navicat 15 激活码 3月最新注册码,https://javaforall.cn/100143.html。详细ieda激活码不妨到全栈程序员必看教程网一起来了解一下吧!

  • mysql密码更改_mysql初始密码在哪个文件

    mysql密码更改_mysql初始密码在哪个文件若使用mysqld–initialize初始化mysql数据库,会产生一个默认的随机密码。密码位置:mysql安装目录下的data目录下的xxx.err文件,此文件如下所示:用记事本打开err文件可以看到临时密码:&lt;a5F34))PqMb使用cmd命令行工具,用临时密码登录,进行修改密码命令:mysql-uroot-p修改密码sqlsetpasswordfo…

  • 奉劝那些想把编程学好的学弟学妹们!呕心沥血,袒露心声,掏心掏肺

    奉劝那些想把编程学好的学弟学妹们!呕心沥血,袒露心声,掏心掏肺CSDN的小伙伴们,大家好,我是沉默王二。作为CSDN的前排博主(18万+关注,有点飘了哈),我接触了太多太多想学编程、想把编程学好的人,有从别的专业转过来的,有零基础自学的,有科班出身的。他们当中的一部分人,学着学着就放弃了,或者还在放弃的路上。所以真的想掏心掏肺给大家谈一谈,在学好编程这条路上,我们该做好哪些心理准备,该怎么去学。01、很遗憾我上大学那会,学校的计算机专业刚成立两年,也就是说,我们是第二批。据说,第一批做小白鼠的学长学姐们,很多在毕业的时候都没从事计算机专业方面的工作。倒

  • SQL索引优缺点

    SQL索引优缺点前两篇文章我总结了一些SQL数据库索引的问题,这篇主要来分析下索引的优缼点,以及如何正确使用索引。索引的优点:这个显而易见,正确的索引会大大提高数据查询,对结果进行排序、分组的操作效率。索引的缺点:优点显而易见,同样缺点也是显而易见:1:创建索引需要额外的磁盘空间,索引最大一般为表大小的1.2倍左右。2:在表数据修改时,例如增加,删除,更新,都需要维护索引表,这是需要系统开销的

  • python爬虫滑动验证码_python爬虫爬取京东优惠线报

    python爬虫滑动验证码_python爬虫爬取京东优惠线报如何自动登陆京东?我们先来看一下京东的登陆页面,如下图所示:【插入图片,登陆页面】登陆框就是右面这一个框框了,但是目前我们遇到一个困呐,默认的登陆方式是扫码登陆,如果我们想要以用户民个、密码的形式登陆,就要切换一下。我们看一下这两种登陆方式是如何切换的,通过浏览器的元素检查,我们看一下两个标签。【插入图片,两种登陆方式】扫码登陆和用户登陆分别在一个div标签里面,我们可以通过css选择器选定用户登…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号