您的位置:首页 > 其它

疯狂Activiti6.0连载(5)流程引擎的创建

2017-10-01 00:00 447 查看
本文节选自《疯狂工作流讲义(第2版)》
京东购买地址:https://item.jd.com/12246565.html
疯狂Activiti电子书:https://my.oschina.net/JavaLaw/blog/1570397
工作流Activiti教学视频:https://my.oschina.net/JavaLaw/blog/1577577

5 流程引擎的创建

前面章节,讲述了Activiti的配置,根据这些配置,可以创建相应的流程引擎。Activiti提供了多种创建流程引擎的方式供研发人员选择,可以通过ProcessEngineConfiguration的buildProcessEngine方法,也可以使用 ProcessEngines的init方法来创建ProcessEngine实例,可以根据项目的不同需要来选择不同的创建方式。

5.1 ProcessEngineConfiguration的buildProcessEngine方法

前面的章节,使用ProcessEngineConfiguration的create方法可以得到ProcessEngineConfiguration的实例。ProcessEngineConfiguration中提供了一个buildProcessEngine方法,该方法返回一个ProcessEngine实例。代码清单5-1中使用buildProcessEngine方法。
代码清单5-1:codes\05\5.1\build-engine\src\org\crazyit\activiti\BuildProcessEngine.java
/**
* @param args
*/
public static void main(String[] args) {
// 读取配置
ProcessEngineConfiguration config = ProcessEngineConfiguration
.createProcessEngineConfigurationFromResource("build_engine.xml");
// 创建ProcessEngine
ProcessEngine engine = config.buildProcessEngine();
}

得到流程引擎的相关配置后,buildProcessEngine方法会根据这些配置,初始化流程引擎的相关服务和对象,包括数据源、事务、拦截器、服务组件等等。这个流程引擎的初始化过程,实际上也可以看作是一个配置检查的过程。

5.2 ProcessEngines对象

除了ProcessEngineConfiguration的buildProcessEngine方法外,ProcessEngines类提供了创建ProcessEngineConfiguration实例的方法。ProcessEngines是一个创建流程引擎与关闭流程引擎的工具类,所有创建(包括其他方式创建)的ProcessEngine实例均被注册到ProcessEngines中。这里所说的注册,实际上是ProcessEngines类中维护一个Map对象,该对象的key为ProcessEngine实例的名称,value为ProcessEngine的实例,当向ProcessEngines注册ProcessEngine实例时,实际上是调用Map的put方法,将该实例缓存到Map中。

5.2.1init与getDefaultProcessEngine方法

ProcessEngines的init方法,会读取Activiti的默认配置文件,然后将创建的ProcessEngine实例缓存到Map中。这里所说的默认配置文件,一般情况下是指ClassPath下的activiti.cfg.xml,如果有与Spring进行整合,则读取ClassPath下的activiti-context.xml文件。代码清单5-2为调用ProcessEngines的init方法。
代码清单5-2:codes\05\5.2\init-engine\src\org\crazyit\activiti\Init.java
public static void main(String[] args) {
// 初始化ProcessEngines的Map,
// 再加载Activiti默认的配置文件(classpath下的activiti.cfg.xml文件)
// 如果与Spring整合,则读取classpath下的activiti-context.xml文件
ProcessEngines.init();
// 得到ProcessEngines的Map
Map<String, ProcessEngine> engines = ProcessEngines.getProcessEngines();
System.out.println(engines.size());
System.out.println(engines.get("default"));
}

调用了init方法后,Activiti会根据默认配置创建ProcessEngine实例,此时Map的key值为“default”,代码清单输出结果如下:
1
org.activiti.engine.impl.ProcessEngineImpl@a23610

此处的init方法并不会返回任何的ProcessEngine实例,该方法只会加载classpath下全部的Activiti配置文件并且将创建的ProcessEngine实例保存到ProcessEngines中。如果需要得到相应的ProcessEngine实例,可以使用getProcessEngines方法拿到ProcessEngines中全部的ProcessEngine实例,getProcessEngines返回的是一个Map,只需要根据ProcessEngine的名称,即可得到相应的ProcessEngine实例。
另外,ProcessEngines提供了一个getDefaultProcessEngine方法,用于返回key为“default”的ProcessEngine实例,该方法会判断ProcessEngines是否进行初始化,如果没有,则会调用init方法进行初始化。

5.2.2registerProcessEngine和unregister方法

注册和注销方法,registerProcessEngine方法向ProcessEngines中注册一个ProcessEngine实例,unregister方法则向ProcessEngines中注销一个ProcessEngine实例。注册与注销ProcessEngine实例,均会根据该ProcessEngine实例的名称进行操作,因为Map的key使用的是ProcessEngine的名称。使用代码清单5-3读取自定义配置,然后创建ProcessEngine实例,并注册到ProcessEngines中,最后调有unregister方法注销该实例。
代码清单5-3:codes\05\5.2\register-engine\src\org\crazyit\activiti\Register.java
public static void main(String[] args) {
//读取自定义配置
ProcessEngineConfiguration config = ProcessEngineConfiguration.
createProcessEngineConfigurationFromResource("register.xml");
//创建ProcessEngine实例
ProcessEngine engine = config.buildProcessEngine();
//获取ProcessEngine的Map
Map<String, ProcessEngine> engines = ProcessEngines.getProcessEngines();
System.out.println("注册后引擎数:" + engines.size());
//注销ProcessEngine实例
ProcessEngines.unregister( engine);
System.out.println("调用unregister后引擎数:" + engines.size());
}


5.2.3retry方法

如果Activiti在加载配置文件时出现异常,可以调用ProcessEngines的retry方法重新加载配置文件,重新创建ProcessEngine实例并加入到Map中。代码清单5-4使用retry方法加载配置文件。
代码清单5-4:codes\05\5.2\retry-engine\src\org\crazyit\activiti\Retry.java
public static void main(String[] args) {
//得到资源文件的URL实例
ClassLoader cl = Retry.class.getClassLoader();
URL url = cl.getResource("retry.xml");
//调用retry方法创建ProcessEngine实例
ProcessEngineInfo info = ProcessEngines.retry(url.toString());
//得到流程实例保存对象
Map<String, ProcessEngine> engines = ProcessEngines.getProcessEngines();
System.out.println("调用retry方法后引擎数:" + engines.size());
}

最后输出结果为1,成功使用retry方法加载资源,创建ProcessEngine实例。在此需要注意的是,retry方法返回的是一个ProcessEngineInfo实例。

5.2.4destroy方法

ProcessEngines的destroy方法,顾名思义,是对其所有维护的ProcessEngine实例进行销毁,并且在销毁时,会调用全部ProcessEngine实例的close方法。代码清单5-5使用destory方法。
代码清单5-5:codes\05\5.2\destroy-engine\src\org\crazyit\activiti\Destroy.java
public static void main(String[] args) {
// 进行初始化并且返回默认的ProcessEngine实例
ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();
System.out.println("调用getDefaultProcessEngine方法后引擎数量:"
+ ProcessEngines.getProcessEngines().size());
// 调用销毁方法
ProcessEngines.destroy();
// 最终结果为0
System.out.println("调用destroy方法后引擎数量:"
+ ProcessEngines.getProcessEngines().size());

// 得到资源文件的URL实例
ClassLoader cl = Destroy.class.getClassLoader();
URL url = cl.getResource("activiti.cfg.xml");
// 调用retry方法创建ProcessEngine实例
ProcessEngines.retry(url.toString());
System.out.println("只调用 retry方法后引擎数量:"
+ ProcessEngines.getProcessEngines().size());
// 调用销毁方法,没有效果
ProcessEngines.destroy();
System.out.println("调用destory无效果,引擎数量:"
+ ProcessEngines.getProcessEngines().size());
}

ProcessEngine实例销毁的前提是ProcessEngines的初始化状态为true,如果为false,则调用destory不会有效果。例如调用retry方法,再调用destory方法,则不会有销售效果,因为retry方法并没有设置初始化状态。代码清单5-5的输出结果:
调用getDefaultProcessEngine方法后引擎数量:1
调用destroy方法后引擎数量:0
只调用 retry方法后引擎数量:1
调用destory无效果,引擎数量:1

在destory执行时,会调用全部ProcessEngine实例close方法,该方法会将异步执行器(AsyncExecutor)关闭,如果流程引擎配置的数据库策略为create-drop,则会执行数据表的删除操作。

5.3 ProcessEngine对象

在Activiti中,一个ProcessEngine实例代表一个流程引擎,ProcessEngine保存着各个服务组件的实例,根据这些服务组件,可以操作流程实例、任务、系统角色等数据。本小节将简述ProcessEngine以及其维护的各个服务组件实例。

5.3.1 服务组件

当创建了流程引擎实例后,在ProcessEngine中会初始化一系列服务组件,这些组件提供了很多控制流程引擎的业务方法,它们就好像J2EE中的Service层,可以使用ProcessEngine中的getXXXService方法得到这些组件的实例。一个ProcessEngine主要有以下实例:
 RepositoryService:提供一系列管理流程定义和流程部署的API。
 RuntimeService:在流程运行时对流程实例进行管理与控制。
 TaskService:对流程任务进行管理,例如任务提醒、任务完成和创建任务等。
 IdentityService:提供对流程角色数据进行管理的API,这些角色数据包括用户组、用户及它们之间的关系。
 ManagementService:提供对流程引擎进行管理和维护的服务。
 HistoryService:对流程的历史数据进行操作,包括查询、删除这些历史数据。
 DynamicBpmnService:使用该服务,可以不需要重新部署流程模型,就可以实现对流程模型的部分修改。
代码清单5-6中,展示了如何获取这些服务组件实例及它们的实现类。
代码清单5-6:codes\05\5.3\engine-service\src\org\crazyit\activiti\GetService.java
public static void main(String[] args) {
//读取流程引擎配置
ProcessEngineConfiguration config = ProcessEngineConfiguration.
createProcessEngineConfigurationFromResource("service.xml");
//创建流程引擎
ProcessEngine engine = config.buildProcessEngine();
//得到各个业务组件实例
RepositoryService repositoryService = engine.getRepositoryService();
RuntimeService runtimeService = engine.getRuntimeService();
TaskService taskService = engine.getTaskService();
IdentityService identityService = engine.getIdentityService();
ManagementService managementService = engine.getManagementService();
HistoryService historyService = engine.getHistoryService();
DynamicBpmnService dynamicBpmnService = engine.getDynamicBpmnService();
// 输入类名
System.out.println(repositoryService.getClass().getName());
System.out.println(runtimeService.getClass().getName());
System.out.println(taskService.getClass().getName());
System.out.println(identityService.getClass().getName());
System.out.println(managementService.getClass().getName());
System.out.println(historyService.getClass().getName());
System.out.println(dynamicBpmnService.getClass().getName());

}

代码清单5-6中的粗体部分,使用ProcessEngine得到保个服务组件实例,这些服务器组件的详细使用,将会在后面章节详细的讲解,运行代码清单5-6,可以看到每一个业务组件的实现类,实现类的命名规则为接口名称加“Impl”:
org.activiti.engine.impl.RepositoryServiceImpl
org.activiti.engine.impl.RuntimeServiceImpl
org.activiti.engine.impl.TaskServiceImpl
org.activiti.engine.impl.IdentityServiceImpl
org.activiti.engine.impl.ManagementServiceImpl
org.activiti.engine.impl.HistoryServiceImpl
org.activiti.engine.impl.DynamicBpmnServiceImpl

注:ProcessEngine中还维护表单相关的服务组件,我们将在表单引擎一章中讲述。

5.3.2 关闭流程引擎

根据前面章节可知,ProcessEngines实例在销毁时,会调用全部ProcessEngine的close方法,会对流程引擎进行关闭操作,这些操作包括关闭异步执行器(AsyncExecutor)和执行数据库表删除(drop),需要让其删除数据表,前提是要将流程引擎配置的databaseSchemaUpdate属性设置为create-drop。代码清单5-7为执行close方法,运行前请将全部数据表删除。
代码清单5-7:codes\05\5.3\close-engine\src\org\crazyit\activiti\Close.java
public static void main(String[] args) throws Exception {
//读取配置
ProcessEngineConfiguration config = ProcessEngineConfiguration.
createProcessEngineConfigurationFromResource("close.xml");
//创建流程引擎
ProcessEngine engine = config.buildProcessEngine();
System.out.println("完成流程引擎创建");
Thread.sleep(10000);
//执行close方法
engine.close();
}

注意代码清单使用了Thread.sleep方法,可以利用暂停的这10秒钟时间去查看数据库的表是否已经创建成功,10秒后执行close方法,以下为代码清单5-7输出的日志信息:
22:21:43,348  INFO DbSqlSession - performing create on engine with resource org/activiti/db/create/activiti.mysql.create.engine.sql
22:21:43,348  INFO DbSqlSession - Found MySQL: majorVersion=5 minorVersion=6
22:21:43,355  INFO DefaultManagementAgent - JMX Connector thread started and listening at: service:jmx:rmi:///jndi/rmi://AY-PC:1099/jmxrmi/activiti
22:22:48,881  INFO DbSqlSession - performing create on history with resource org/activiti/db/create/activiti.mysql.create.history.sql
22:22:48,882  INFO DbSqlSession - Found MySQL: majorVersion=5 minorVersion=6
22:23:04,069  INFO DbSqlSession - performing create on identity with resource org/activiti/db/create/activiti.mysql.create.identity.sql
22:23:04,070  INFO DbSqlSession - Found MySQL: majorVersion=5 minorVersion=6
22:23:08,724  INFO ProcessEngineImpl - ProcessEngine default created
完成流程引擎创建
22:23:18,948  INFO DbSqlSession - performing drop on engine with resource org/activiti/db/drop/activiti.mysql.drop.engine.sql
22:23:18,965  INFO DbSqlSession - Found MySQL: majorVersion=5 minorVersion=6
22:23:33,613  INFO DbSqlSession - performing drop on history with resource org/activiti/db/drop/activiti.mysql.drop.history.sql
22:23:33,613  INFO DbSqlSession - Found MySQL: majorVersion=5 minorVersion=6
22:23:42,030  INFO DbSqlSession - performing drop on identity with resource org/activiti/db/drop/activiti.mysql.drop.identity.sql
22:23:42,030  INFO DbSqlSession - Found MySQL: majorVersion=5 minorVersion=6

注意以上输出信息的粗体部分,完成了流程引擎创建后,由于调用了close方法,并且databaseSchemaUpdate属性设置为create-drop,因此Activiti会执行相应数据库的drop脚本。
注:运行代码清单5-7前,需要先将数据库中的全部数据表删除。

5.3.3 流程引擎名称

根据前面章节可以知道, 每个ProcessEngine实例均有自己的名称,在ProcessEngines的Map中,会使用该名称作为Map的key值,如果不为 ProcessEngine设置名称的话,Activiti会默认的将其设置为“default”。ProcessEngine本身没有提供设置名称的方法,该方法由ProcessEngineConfiguration提供。代码清单5-8为ProcessEngine设置名称。
代码清单5-8:codes\05\5.3\engine-name\src\org\crazyit\activiti\Name.java
public static void main(String[] args) {
ProcessEngineConfiguration config = ProcessEngineConfiguration.
createProcessEngineConfigurationFromResource("name.xml");
//设置流程引擎名称
config.setProcessEngineName("test");
ProcessEngine engine = config.buildProcessEngine();
//根据名称查询流程引擎
ProcessEngine engineTest = ProcessEngines.getProcessEngine("test");
System.out.println("创建的引擎实例:" + engine);
System.out.println("查询的引擎实例:" + engineTest);
}

代码清单5-8中的粗体字代码,调用了ProcessEngineConfiguration的setProcessEngineName方法将流程引擎名称设置为test,然后根据该名称到ProcessEngines中查询相应的流程引擎,代码输出结果两个引擎均为同一对象。由此可知,buildProcessEngine方法实际上完成了ProcessEngines的register操作,运行代码清单5-8,输出结果如下:
创建的引擎实例:org.activiti.engine.impl.ProcessEngineImpl@16fe72b
查询的引擎实例:org.activiti.engine.impl.ProcessEngineImpl@16fe72b


5.4本章小节

本章内容主要讲述了如何利用Activiti的配置创建流程引擎对象(ProcessEngine)。本章中所述的创建流程引擎对象的方法有两种:ProcessEngineConfiguration的buildProcessEngine方法、ProcessEngines的init方法,除此之外,如果项目中使用了Spring,还可以将ProcessEngine作为一个bean配置到XML文件中,然后使用Spring的API获取。
本章内容较为简单,最基本要掌握ProcessEngines与ProcessEngine的使用就已经完成任务,对于本章中一些关于实现原理的描述,如不感兴趣可不必掌握。
本文节选自《疯狂工作流讲义(第2版)》
京东购买地址:https://item.jd.com/12246565.html
疯狂Activiti电子书:https://my.oschina.net/JavaLaw/blog/1570397
工作流Activiti教学视频:https://my.oschina.net/JavaLaw/blog/1577577
本书代码目录:https://gitee.com/yangenxiong/CrazyActiviti



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  activiti6 工作流