工作流(Workflow),指“业务过程的部分或整体在计算机应用环境下的自动化”。是对工作流程及其各操作步骤之间业务规则的抽象、概括描述。 通俗的说,流程(过程)就是多个人在一起合作完成某件事情的步骤,把步骤编程计算机能理解的形式,就是工作流。 工作流是研究一个群体如何在计算机的帮助下实现协同工作的,其主要解决的问题是:为了实现某个业务目标,利用计算机在多个参与者(Actor)之间按某种预定规则自动传递文档、信息或者任务(Task)。
【不使用工作流技术:】 从头开始开发这个订购流程的业务逻辑,我们需要: - 每个活动点都需要开发交互页面和后台处理程序 - 每个活动的流转都需要硬性判断下一步活动节点及其操作人 - 每次操作都需要维护业务数据和流程的相关数据
使用好处: - 使用专门的流程数据系统,维护所有涉及流程流转的数据。 - 提供“流程设计”工具,帮助用户定义订货流程的模型,而且一般都提供了可视化的界面。 - 所有的流程都依靠流程引擎来处理,避免了需求更改与硬编码之间矛盾的产生。 - 工作流引擎还提供了众多的API,可以很方便的将工作流的管理和业务操作完美结合。
工作流只管理流程,是不能完成业务操作的。换句话说,工作流是相对独立的、通用的,与业务管理无直接关系。 比如费用报销流程,工作流管理的是报销的流程(谁申请,谁审批),费用报销的业务(使用费用的原因,使用费用的时间,,) 工作流虽然与业务无直接关系,但是,在开发的时候,需要考虑和业务整合。
Activiti、JBPM、OSWorkflow、ActiveBPEL、YAWL等。
Activiti是一套业务流程管理(BPM)框架,它覆盖了业务流管理、工作流、服务协助等领域,它是一个开源的(Apache许可2.0)、灵活的、易扩展的可执行流程语言框架。 Activiti是Alfresco软件在2010年5月17日宣布启动的一个开源项目,其创始人和首席架构师由业务流程管理BPM的专家 Tom Baeyens担任。Tom Baeyens是JBoss jBPM的项目架构师。 提示:Jbpm4版本之后,该作者才做的Activiti,所以,Activiti很像jbpm4,理念又有点像hibernate。但是,jbpm5与4版本的差距比较大。
它是一项新的基于Apache许可的开源BPM平台,从基础开始构建,提供支持新的BPMN 2.0标准。(直观的认识就是XML) Activiti提供了流程设计器,开发人员可以直接通过流程设计器直接画出业务流程图。 Activiti的持久层使用的Mybatis。(api将dao封装了,无需会mybatis)
第一步:用管理员进去定制流程。 第二步:部署和启动流程。 第三步:使用流程。
使用工作流系统需要三步: 1.画流程图(流程文档xml定义)—管理员 2.部署到工作流的系统中—管理员 3.启动流程,开始执行任务,直到任务结束。–用户
Maven坐标(工作流引擎activiti-engine,日志实现slf4j-log4j12,数据库驱动oracle,测试junit):
<properties> <activiti.version>5.19.0.2</activiti.version> <slf4j.version>1.7.5</slf4j.version> <oracle.version>10.2.0.4.0</oracle.version> <c3p0.version>0.9.1.2</c3p0.version> <junit.version>4.11</junit.version> </properties> <dependencies> <dependency> <groupId>org.activiti</groupId> <artifactId>activiti-engine</artifactId> <version>${activiti.version}</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>${slf4j.version}</version> </dependency> <dependency> <groupId>com.oracle</groupId> <artifactId>ojdbc14</artifactId> <version>${oracle.version}</version> <scope>runtime</scope> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>${junit.version}</version> <scope>test</scope> </dependency> </dependencies>新建一个测试类:
/** * Activiti测试类 */ @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations="classpath:applicationContext.xml") public class ActivitiTest { //创建表:通过创建工厂(流程引擎:用来生成其他的服务api来具体操作) @Test public void testCreateTable(){ //1.得到引擎的配置对象:单服务器使用 ProcessEngineConfiguration processEngineConfiguration = ProcessEngineConfiguration.createStandaloneProcessEngineConfiguration(); //2.在引擎配置对象上设置相应的数据库连接参数 processEngineConfiguration.setJdbcDriver("oracle.jdbc.driver.OracleDriver"); processEngineConfiguration.setJdbcUrl("jdbc:oracle:thin:@localhost:1521:xe"); processEngineConfiguration.setJdbcUsername("bos"); processEngineConfiguration.setJdbcPassword("bos"); //设置自动建表 //三种参数值: //false:只是检查表结构,但不创建也不更新。适合已经有表的时候用 //create-drop:启动的时候检查和创建表,引擎关闭的是的删除 //true:检查表结构,如果表存在,则创建,如果表结构不一致,则更新。---常用 processEngineConfiguration.setDatabaseSchemaUpdate(processEngineConfiguration.DB_SCHEMA_UPDATE_TRUE); //获取工作流引擎对象(单例) ProcessEngine processEngine = processEngineConfiguration.buildProcessEngine(); System.out.println("====="+processEngine); } }ProcessEngine:流程引擎接口,是最核心的API类,其他的API类都由他而来。它是其他API产生的基础!ProcessEngine对象,这是Activiti工作的核心。负责生成流程运行时的各种实例及数据、监控和管理流程的运行。
RepositoryService 流程定义管理 操作 ACT_RE_* 数据表 RuntimeService 流程实例管理 操作 ACT_RU_* 数据表 TaskService 任务管理 操作 ACT_RU_TASK 数据表IdentitiService 认证管理 操作 ACT_ID_* 数据表 HistoryService 历史记录管理 操作 ACT_HI_* 数据表 ManagementService 定时任务管理,创建job,ACT_RU_JOB 数据表FormService 表单管理,生成动态任务表单页面,某个字段存的数据maven坐标
<dependency> <groupId>org.activiti</groupId> <artifactId>activiti-engine</artifactId> <version>${activiti.version}</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>${slf4j.version}</version> </dependency>ApplicationContext.xml:
<!-- 流程引擎配置对象 --> <bean id="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration"> <!-- 注入数据源 --> <property name="dataSource" ref="dataSource"/> <!-- 自动建表 --> <property name="databaseSchemaUpdate" value="true"/> </bean> <!-- 流程引擎对象 --> <bean id="processEngine" factory-bean="processEngineConfiguration" factory-method="buildProcessEngine"/>流程id(非常重要-将来程序里面叫key—流程定义的唯一标识),必须英文. 添加办理人:
Bpmn文件解读:
关于工作流的api,有个规律:要获取某对象,都是createXxx; 如果是CreateXxx,获取的就是xxx对象,该对象主要用来增删改对应的表。 如果是CreateXxxQuery,获取的是xxxQuery对象,该对象主要用来查询的。
加载流程文档的时候,可以单独加载文档bpmn,工作流会自动生成一张图片存在数据库。 但也可以两个都加载,那么工作流就不会自动生成图片,而使用你上传的图片。
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration( locations="classpath:applicationContext.xml") public class ActivitiTest { //注入仓库Service @Autowired private RepositoryService repositoryService; //发布流程:只发布流程图,自动生成图片 @Test public void deployment1(){ Deployment deployment = repositoryService.createDeployment()//获取发布对象 .addClasspathResource("diagrams/Leave.bpmn")//添加流程文件 .name("请假流程1")//发布的名字 .deploy();//发布 System.out.println("发布的编号:"+deployment.getId()); System.out.println("发布的名称:"+deployment.getName()); System.out.println("发布的时间:"+deployment.getDeploymentTime()); } //发布流程:发布流程图和图片--第一种方法 @Test public void deployment21(){ Deployment deployment = repositoryService.createDeployment()//获取发布对象 .addClasspathResource("diagrams/Leave.bpmn")//添加流程文件 .addClasspathResource("diagrams/Leave.png")//添加流程图片 .name("请假流程21")//发布的名字 .deploy();//发布 System.out.println("发布的编号:"+deployment.getId()); System.out.println("发布的名称:"+deployment.getName()); System.out.println("发布的时间:"+deployment.getDeploymentTime()); } //发布流程:发布流程图和图片--第二种方法 @Test public void deployment22() throws FileNotFoundException{ Deployment deployment = repositoryService.createDeployment()//获取发布对象 .addZipInputStream(new ZipInputStream(this.getClass().getClassLoader().getResourceAsStream("diagrams/Leave.zip"))) .name("请假流程22")//发布的名字 .deploy();//发布 System.out.println("发布的编号:"+deployment.getId()); System.out.println("发布的名称:"+deployment.getName()); System.out.println("发布的时间:"+deployment.getDeploymentTime()); } }ApplicationContext.xml:
<!-- 流程控制的相关service --> <!-- 仓库对象 --> <bean id="repositoryService" factory-bean="processEngine" factory-method="getRepositoryService"></bean>工作流服务端自动生成的图片的乱码问题解决方案: 解决方案1: 在流程引擎配置对象上面设置字体属性:
<!-- 发布流程生成图片是正常显示中文 --> <property name="activityFontName" value="宋体"/> <property name="labelFontName" value="宋体"/>解决方案2: 流程图的图片在设计器中生成好,上传到服务器,不让服务器自动生成图片。
级联和不级联。 场景:如果流程已经开启了,如果不使用级联,则会抛出异常!(原因:定义表有外键关联它),此时只能用级联。
applicationContext.xml配置:
<!-- 运行时Service --> <bean id="runtimeService" factory-bean="processEngine" factory-method="getRuntimeService"/>当end节点之前的节点办理完成后,会自动完成end节点。当前流程实例都结束了。