如果不結(jié)合其他的框架進行整個開發(fā)(如:spring、hibernate),JBPM4也有自己的一套IOC容器,能后將自己的服務(wù)配置到IOC容器中,能夠很容易的運行容器所配置的服務(wù),
這樣它也能夠在代碼中減少一陀一陀的工廠類等代碼的調(diào)用,降低了偶核性,但是如果結(jié)合spring框架來進行整個開發(fā)的話,那么就有兩個容器,兩個SessionFactory,但是系統(tǒng)中只考慮一個容器來
對服務(wù)進行管理, 那么我們就要將jbpm4的服務(wù)移植到spring的IOC容器中,讓spring來進行統(tǒng)一管理,這樣通過spring的容器來管理服務(wù)、事務(wù)。
在網(wǎng)上,不管是百度、還是谷歌 搜索了一下,截至到目前(2009-08-29),沒有搜索出一個JBPM4結(jié)合其他框架的完成例子,都是一些簡單的介紹,而且所有文章大同小異,雖然文章上千章,但是好像出自
一個之手,但是此人也只是大概講解了一下,可能有些人會認(rèn)為用JBPM4結(jié)合其他框架進行整合是非常簡單,那么你的想法是錯誤的,JBPM4整合其他框架對JBPM4的IOC理解要非常清楚,同時,要對部分源代碼進行了解,才可能一步一步的搭建起來框架,下面介紹下我以struts2+spring2.5+hibernate3.4+jbpm4來搭建的一個框架,并且成功部署的過程
ssh2的框架搭建我這里就不啰嗦了,我主要就這個框架的基礎(chǔ)上來整合jbpm4
第一步:加入jbpm4的jpdl插件,這個步驟非常簡單,但是可能會出現(xiàn)下面的錯誤
把jbpm4加入到項目中遇到的問題:
無法導(dǎo)入插件jpdl(導(dǎo)入插件后沒有出現(xiàn)可視化流程操作器的入口,無法進行可視化流程建立)
解決方法:
先前本人使用myeclipse6.0.1,在此版本上本人做過JBPM3的項目,在做JBPM4時,很自然的想到在該IDE上進行JBPM4的開發(fā),但是一直都無法成功江JBPM4的jpdl插件安裝成功,因此
不斷的換各種安裝插件的方式,浪費了很多時間,后無意在myclipse7.1.1中嘗試安裝jpdl插件,竟然成功,后才發(fā)現(xiàn)myeclipse6不支持jbpm4,最終本人選擇IDE myclipse7.1.1來進行
開發(fā).
第二步:創(chuàng)建JBPM4的數(shù)據(jù)庫文件、JBPM4相關(guān)jar包、JBPM4的相關(guān)配置文件
數(shù)據(jù)庫文件:解壓下載的jbpm4.0, jbpm4.0根目錄下的db\schema.scripts目錄下,這里存放的是jbpm4數(shù)據(jù)庫文件的腳本,根據(jù)自己的需要選擇相應(yīng)數(shù)據(jù)庫腳本文件進行導(dǎo)入
JBPM4的jar包:jbpm4.0根目錄下jbpm.jar
jbpm4-spring.jar,這兩個jar文件內(nèi)容大致相同,但是某些類也是對方所不具有的
lib目下的相關(guān)jar包(不要全部導(dǎo)入,因為這里包含hibernate,還有一些公共的jar包,可能你的工程中已經(jīng)含有這些jar包,根據(jù)需要導(dǎo)入相關(guān)的jar包即可)
JBPM4的相關(guān)配置文件:
鑒于大家jbpm對配置文件位置的存放不清楚,以及因為版本的不同,造成文件內(nèi)容和文件名不一樣,所以對需要在項目中導(dǎo)入的文件及內(nèi)容(基本配置)做了一個總結(jié):
jbpm.cfg.xml,內(nèi)容如下:
<?xml version="1.0" encoding="UTF-8"?>
<jbpm-configuration>
<import resource="jbpm.spring.default.cfg.xml" />
<import resource="jbpm.spring.hibernate.cfg.xml" />
<import resource="jbpm.jpdl.cfg.xml" />
<import resource="jbpm.identity.cfg.xml" />
<!-- Job executor is excluded for running the example test cases. -->
<!-- To enable timers and messages in production use, this should be included. -->
<!--
<import resource="jbpm.jobexecutor.cfg.xml" />
-->
<import resource="jbpm.mail.templates.examples.xml" />
</jbpm-configuration>

jbpm.mail.properties,文件內(nèi)容:
mail.smtp.host localhost
mail.smtp.port 2525
mail.from noreply@jbpm.org
jbpm.mail.templates.examples.xml,文件內(nèi)容:
<?xml version="1.0" encoding="UTF-8"?>
<jbpm-configuration>
<process-engine-context>
<mail-template name="rectify-template">
<to addresses="${addressee}" />
<cc users="bb" groups="innerparty" />
<bcc groups="thinkpol" />
<subject>rectify ${newspaper}</subject>
<text>${newspaper} ${date} ${details}</text>
</mail-template>
</process-engine-context>
</jbpm-configuration>

jbpm.spring.default.cfg.xml,文件內(nèi)容:
<?xml version="1.0" encoding="UTF-8"?>
<jbpm-configuration>
<process-engine-context>
<repository-service />
<repository-cache />
<execution-service />
<history-service />
<management-service />
<identity-service />
<task-service />
<!--
<hibernate-configuration>
<cfg resource="jbpm.hibernate.cfg.xml" />
</hibernate-configuration>
<hibernate-session-factory />
-->
<script-manager default-expression-language="juel"
default-script-language="juel"
read-contexts="execution, environment, process-engine"
write-context="">
<script-language name="juel" factory="org.jbpm.pvm.internal.script.JuelScriptEngineFactory" />
</script-manager>
<authentication />
<id-generator />
<types resource="jbpm.variable.types.xml" />
<address-resolver />
<business-calendar>
<monday hours="9:00-12:00 and 12:30-17:00"/>
<tuesday hours="9:00-12:00 and 12:30-17:00"/>
<wednesday hours="9:00-12:00 and 12:30-17:00"/>
<thursday hours="9:00-12:00 and 12:30-17:00"/>
<friday hours="9:00-12:00 and 12:30-17:00"/>
<holiday period="01/07/2008 - 31/08/2008"/>
</business-calendar>
<mail-template name='task-notification'>
<to users="${task.assignee}"/>
<subject>${task.name}</subject>
<text><![CDATA[Hi ${task.assignee},
Task "${task.name}" has been assigned to you.
${task.description}
Sent by JBoss jBPM
]]></text>
</mail-template>
<mail-template name='task-reminder'>
<to users="${task.assignee}"/>
<subject>${task.name}</subject>
<text><![CDATA[Hey ${task.assignee},
Do not forget about task "${task.name}".
${task.description}
Sent by JBoss jBPM
]]></text>
</mail-template>
</process-engine-context>
<transaction-context>
<repository-session />
<db-session />
<message-session />
<timer-session />
<history-session />
<mail-session>
<mail-server>
<session-properties resource="jbpm.mail.properties" />
</mail-server>
</mail-session>
</transaction-context>
</jbpm-configuration>

jbpm.spring.hibernate.cfg.xml,文件內(nèi)容:
<?xml version="1.0" encoding="UTF-8"?>
<jbpm-configuration>
<process-engine-context>
<command-service>
<retry-interceptor />
<environment-interceptor />
<spring-transaction-interceptor />
</command-service>
</process-engine-context>
<transaction-context>
<transaction />
<hibernate-session />
</transaction-context>
</jbpm-configuration>

logback.xml,文件內(nèi)容:
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<layout class="ch.qos.logback.classic.PatternLayout">
<Pattern>%d{HH:mm:ss.SSS} %-5level %logger{36} - %msg%n</Pattern>
<!--
<pattern>%date [%thread] %-5level %logger{80} - %msg%n</pattern>
-->
</layout>
</appender>
<root level="info">
<appender-ref ref="STDOUT" />
</root>
</configuration>
sql-error-codes.xml,文件內(nèi)容:
該文件內(nèi)容較多,搜索一下jbpm4.0包下的文件,應(yīng)該都有
上述文件存放在src目錄下
第三步:添加JBPM4的服務(wù)到spring IOC容器中
1.jbpm.spring.default.cfg.xml(jbpm.spring.default.cfg.xml)配置文件進行修改,將下面的部分配置注釋掉
<hibernate-configuration>
<cfg resource="jbpm.hibernate.cfg.xml" />
</hibernate-configuration>
<hibernate-session-factory />
注釋的部分是在jBPM4中創(chuàng)建了sessionFactory,因為已經(jīng)有了spring管理sessionFactory,因此我們只需要一個sessionFactory。既然要將jBPM4與Spring的整合,那就希望由Spring來統(tǒng)一管理 sessionFactory和事務(wù),在Spring的配置文件中構(gòu)造一個sessionFactory。一切由它與外部交互.
2.上面已經(jīng)屏蔽了jbpm4的sessionFactory,那么此處要新建立一個ProcessEngineFactoryBean類,該類用來初始化JBPM4的相關(guān)配置文件、工作流引擎,并且把sessionFactory的創(chuàng)建交給spring的容器 進行管理,在ProcessFactoryBean中創(chuàng)建一個SpringConfiguration,然后將sessionFactory放入 SpringConfiguration中,再從SpringConfiguration得到processEngine,代碼如下:
public class ProcessEngineFactoryBean implements FactoryBean,

InitializingBean, DisposableBean, ApplicationContextAware
{
private String jbpmConfigurationLocation = "jbpm.cfg.xml";
private SessionFactory sessionFactory;
private ApplicationContext applicationContext;
private ProcessEngine processEngine;//jbpm4的流程引擎接口,所有的功能服務(wù)都是從這里獲取的,包括RespoistoryService、ExecutionService

public Object getObject() throws Exception
{
return processEngine;
}
@SuppressWarnings("unchecked")

public Class getObjectType()
{
return ProcessEngine.class;
}

public boolean isSingleton()
{
return true;
}

public void afterPropertiesSet()
{
SpringConfiguration cfg = new SpringConfiguration(jbpmConfigurationLocation);
cfg.setApplicationContext(applicationContext);
cfg.setSessionFactory(sessionFactory);
this.processEngine = cfg.buildProcessEngine();
}

public void destroy()
{
this.processEngine = null;
this.sessionFactory = null;
}
public void setJbpmConfigurationLocation(

String jbpmConfigurationLocation)
{
this.jbpmConfigurationLocation = jbpmConfigurationLocation;
}

public void setSessionFactory(SessionFactory sessionFactory)
{
this.sessionFactory = sessionFactory;
}
public void setApplicationContext(

ApplicationContext applicationContext) throws BeansException
{
this.applicationContext = applicationContext;
}
}
并且在Spring配置文件中加入如下配置:
<bean id="processEngine" class="com.bestsoft.ssh.service.impl.flow.ProcessEngineFactoryBean">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
通過上述我們創(chuàng)建了工作流引擎,那么這個時候我們可以通過配置來管理JBPM4中的服務(wù)(ProcessEngine接口中的服務(wù),如:創(chuàng)建流程的服務(wù)、執(zhí)行流程的服務(wù)等),這樣做的目的是不想一陀一陀的工廠 類在代碼中出現(xiàn),由spring的注入功能來實現(xiàn),如下配置(在spring配置文件中):
<bean id="repositoryService" factory-bean="processEngine" factory-method="getRepositoryService" />
<bean id="executionService" factory-bean="processEngine" factory-method="getExecutionService" />
<bean id="historyService" factory-bean="processEngine" factory-method="getHistoryService" />
<bean id="managementService" factory-bean="processEngine" factory-method="getManagementService" />
<bean id="taskService" factory-bean="processEngine" factory-method="getTaskService" />
<bean id="identityService" factory-bean="processEngine" factory-method="getIdentityService" />
添加JBPM4的服務(wù)到spring IOC容器中錯誤:
注意:所有的jbpm4的配置文件必須在src目錄下,并且不能有獨立的目錄,因為在初始化發(fā)布流程的代碼中
ProcessEngine processEngine = new Configuration().buildProcessEngine();
因為JbpmConfiguration extends Configuration implements Context, ProcessEngine, EnvironmentFactory 因此會
調(diào)用JbpmConfiguration類中buildProcessEngine()方法來創(chuàng)建ProcessEngine來得到JBPM4的服務(wù),在這個方法中,有這樣一段代碼
if (!isConfigured) {
setResource("jbpm.cfg.xml");
}

它會去src下找jbpm.cfg.xml文件,如果配置文件不在src目錄下,那么就會找不到配置文件(jbpm.cfg.xml)
第四步:加入JBPM4的實體關(guān)系映射文件:
<property name="mappingLocations">
<list>
<value>classpath*:jbpm.repository.hbm.xml</value>
<value>classpath*:jbpm.execution.hbm.xml</value>
<value>classpath*:jbpm.history.hbm.xml</value>
<value>classpath*:jbpm.task.hbm.xml</value>
<value>classpath*:jbpm.jpdl.hbm.xml</value>
<value>classpath*:jbpm.identity.hbm.xml</value>
</list>
</property>
可能會出現(xiàn)的問題: 啟動中如果提示:找不到org.jbpm.jpdl.internal.model.JpdlExecution,那么這個時候,應(yīng)該添加一個jbpm4-spring.jar文件,因為該jar中有此實體
第五步:
請務(wù)必配置事務(wù),JBPM4已經(jīng)將事務(wù)改成從當(dāng)前的Threadlocal中獲得,所以jBPM4是必須當(dāng)前有事務(wù),如果我沒有創(chuàng)建事務(wù)的話,在使用 processEngine時就會說事務(wù)沒有啟動。
因為該文章是在成功運行后書寫的,可能某些步驟漏寫,或者描述不清楚,而無法成功整合,導(dǎo)致報錯,請大家把報錯信息貼出來,讓我對文章作相應(yīng)的修改,讓參照著能夠成功整合運行。