再难的事情,只要“流程化”了也会变的简单。
最近近在学JBPM,写个小程序来练练手,主要目的是为了总结近期所学。
【Jbpm开发环境的搭建流程】
1. 为Eclipse增加Jbpm插件;
1)找到“D:\Program Files\MyEclipse 6.5\jbpm-starters-kit-3.1.4\jbpm-designer\jbpm-gpd-feature\eclipse”下的"Features","Pulgins"两个文件夹,将其都Copy到“D:\Program Files\MyEclipse 6.5\jbpm”(目的:防止连接时路径太深,可以不Copy的);
2)利用Links方式来为Eclipse装插件;在“D:\Program Files\MyEclipse 6.5\eclipse\links”目录下新建一个.link文件,名字可以任意,内容:path=D:\\Program Files\\MyEclipse 6.5\\jbpm(其中必须为“\\”或是“/”,否则无法识别)。
2. 在MySQL中建立JBPM数据库(利用脚本建立数据库);
1)New DataBase;
2) 导入脚本;File——》open(.sql文件,与将文件中的内容全部copy到“Query”区的功能相同);
3)运行脚本;点击“execute all queries”;
4) 在该数据库上点右键“Refresh Object Brower”(只有这样才能在数据库中看到建立的表);
说明:(1)该数据库必须命名为“JBPM”(MySQL对于数据库名是不区分大小写的);
(2)这个数据库只需要在第一次的时候建一次即可,以后每次写流程就是在里面存储。
每个流程每次部署在其中生成不同主键的“Jbpm_”
【Jbpm项目的建立流程】
1. 导入数据库的驱动包, 修改HIbernate配置文件,连接数据库;
1)因为流程的信息都是要记录在该数据库中的,在写前台调用这个流程的时候实际是在数据库中取一些东西来操作的。
2) 配置MySql时的配置文件,如截图00:
截图00
说明:(1)<property name="hibernate.connection.driver_class">:为数据库JDBC的包中Driver这个类即可,不用再写前面的文件夹名;
(2) <property name="hibernate.connection.url">jdbc:mysql:(不在是Http:)
2. 写流程以及其中的一些Action;流程的设计原则:
1)节点主要完成的功能:设计Variable,既可以传递到Transition中的Action,又可以与前台进行交互;
2) Action主要完成的功能:主要完成一些操作;
本项目中设计的流程如截图01,02:
截图01
截图02
设计的Action如截图03,04:
截图03
截图04
3. 部署流程;其实质就是在JBPM数据库中存入流程的定义的一些内容,需要写一个具有main()方法的Java 类来实现:
1) 得到JbpmConfiguration;
2)通过JbpmConfiguration得到JbpmContext;
3) 将JbpmContext中的ProcessDefinition文件转化为InputStream,
再利用ProcessDefinition.pareXmlInputSteam()得到ProcessDefinition的一个实例;
4)利用该实例的Context的DeployProcessDefinition()来部署该流程实例;
5)该流程实例的Context.Close();(只有关闭后才会在后台DB中有呈现该流程的记录,否则实际已经部署上了但没办法显示)
本项目中的部署类如截图05:
说明:当大流程中嵌套有小流程时,应当先部署小流程再部署大流程,但顺序不能颠倒;
4. 写前台逻辑;具体的流程为:
1) 得到JbpmConfiguration的一个Instance;
2)由该Instance得到JbpmContext;
3) 利用该Session下最新的ProcessDefinition得到一个ProcessDefinition;
4)利用该ProcessDefinition创建一个ProcessInstance;
5)利用该Instance得到其ContextInstance;
本项目的前台设计如截图06.07.08:
截图06
截图07
截图08
说明:(1)使流程一步一步执行,利用的是Single(),而调用这个方法有2种方式:
ProcessInstance.single();
由ProcessInstance先得到Token(即流程执行的“令牌”),再调用该Token.Single();
(2)得到节点的方式有(但是无法得到该节点的Variable):
Token.getNode():得到当前节点;
ProcessDefinition.getNode(“”):利用节点名得到任意节点;
(3) Variable的设计原则及Variable的获得方法:
要在节点间传递的Variable设计为全局的==》在<ProceseeDefinition>中加入<task><controller><variable>;
要在节点内与Transition间传递的Variable要放在节点中==》在相应节点中加入<task><controller><variable>;
==》获得总流程中的Variable:ProcessInstance.getContextInstance()
Token. getContextInstance()
得到Variable就要通过ContextInstance.get/setVariable()
==》获得Action中的Variable:ExecutionContext.getContextInstance()
在Action中也可以定义Variable,<名字是任意的>;
(4)在“ProjectName/src/main”下建类其实质是在“ProjectName/src/main/java”下建,
如截图09
这篇博文的书写过程真是很波折,主要是因为实验室的网路太烂了,第一次本来都写好了,可是掉线了没保存。当时由于刚做完这个小程序所以写的比较有激情,这样一来着实让我小郁闷了一下,结果又因为有别的事情要忙,所以用了三天才写完。在这期间老是上传图片到了一办IE就自动关了结果下次又得重新开始,哎。。。不过这样还是让我有收获的:
1.让我突然想起了一句话“有勇气来改变可以改变的,有胸怀来接受不可以改变的,有智慧来分辨两者的不同”;
2.让我突然有种换一种写Blog的想法,现在Word中写好,把图片都弄好,再Copy进来,不知道可以不可以。。。下次试试。