Abstract
˜q™ç¯‡æ–‡ç« ä¸»è¦æ˜¯ä»‹¾l了(ji¨£n)jBPM 4.0的基¼‹€æž¶æž„,以åŠ(qi¨¢ng)通过一个简å•çš„ä¾‹åæ¥è®©å¤§å®¶çŸ¥é“æ€Žä¹ˆåº”用jBPM. ä¸ÞZ»€ä¹ˆé€‰æ‹©4.0版本å‘?以åŽçš„主‹¹ç‰ˆæœ¬åº”该是4.0版本çš?所以直接写4.0版本的了(ji¨£n).
<jbpm-configuration>
<import resource="jbpm.default.cfg.xml" />
<import resource="jbpm.tx.jta.cfg.xml" />
<import resource="jbpm.jpdl.cfg.xml" />
<import resource="jbpm.identity.cfg.xml" />
<import resource="jbpm.jobexecutor.cfg.xml" />
</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>
...........
</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>
˜q™ä¸ªé…置文äšg主è¦åŒ…å«äº?process-engine-context'å’?'transaction-context'的酾|?
Object get(String key);
<T> T get(Class<T> type);
Object set(String key, Object value);
/**
* constructs the object.
* @param wireContext {@link WireContext} in which the object is created. This is also the {@link WireContext}
* where the object will search for other object that may be needed during the initialization phase.
* @return the constructed object.
*/
Object construct(WireContext wireContext);
/**
*called by the WireContext to initialize the specified object.
*/
void initialize(Object object, WireContext wireContext);
public interface Binding {
String getCategory();
/** does this binding apply to the given element? */
boolean matches(Element element);
/** translates the given element into a domain model java object.
* Use the parse to report problems.
*/
Object parse(Element element, Parse parse, Parser parser);
}
jbpm.cfg.xml �gt; jBPMConfigurationParser -> Binding �gt; Descriptor --> WireContext
或者更清楚çš?我们å¯ä»¥çœ‹ä¸‹ä¸‹é¢˜q™å¼ å›?sup>[
1].
我们ä¸å¦¨ä¹Ÿçœ‹ä¸‹ConfigurationTest‹¹‹è¯•.
public void testConfigurationServices() {
ProcessEngine processEngine = new Configuration()
.setXmlString(
"<jbpm-configuration>" +
" <process-engine-context>" +
" <repository-service />" +
" <execution-service />" +
" <management-service />" +
" </process-engine-context>" +
"</jbpm-configuration>"
)
.buildProcessEngine();
assertNotNull(processEngine);
assertNotNull(processEngine.getExecutionService());
assertNotNull(processEngine.getManagementService());
}
Configuration ¾cÀL˜¯jBPM的入å?ä½ å¯ä»¥ä»Ž Configuration¾cÖM¸åˆ›å¾ProcessEngine,而从ProcessEngineä¸èŽ·å–到RepositoryService, ExecutionService, TaskService½{‰ç‰. Configuration¾c»é‡Œæœ‰ä¸¤ä¸ªå®žçŽ°ç±»,一个是JbpmConfiguration,˜q™æ˜¯é»˜è®¤çš„jBPM自带的Configurationè§£æžå™? å¦å¤–一个是SpringConfiguration,˜q™ä¸ªæ˜¯jBPMå’ŒSpring的集æˆ? 在这é‡?我们ž®±åªçœ‹ä¸‹JbpmConfiguration的实çŽ?在JbpmConfiguration¾c»é‡Œ,我们å¯ä»¥çœ‹åˆ°ä»–是˜q™ä¹ˆåŽ»è°ƒç”¨Parseræ? è§£æžxmlçš?
protected void parse(StreamInput streamSource) {
isConfigured = true;
JbpmConfigurationParser.getInstance()
.createParse()
.pushObject(this)
.setStreamSource(streamSource)
.execute()
.checkErrors("jbpm configuration " + streamSource);
}
在这é‡?我们å¯ä»¥çœ‹åˆ°,jbpm的酾|®æ–‡ä»¶æ˜¯æœ‰ä¸¤ä¸ªå…ƒç´ 组æˆçš„,一个是process-engine-context,å¦å¤–一个是transaction-context. å…¶ä¸process-engine-context里é¢çš„å…ƒç´ æ˜¯åŒ…æ‹¬äº?ji¨£n)对外å‘布的æœåŠ? 比如repository-service, execution-service½{‰ç‰. 而transaction-context则包括了(ji¨£n)他的内部真æ£å®žçް,比如repository-service对应repository-session. 也å¯ä»¥ç®€å•的把repository-servieçœ‹åšæ˜¯API, repository-sessionçœ‹åšæ˜¯SPI. ˜q™æ ·åšçš„好处æ˜?SPI的实çŽ?对API一点媄(ji¨£ng)å“都没有,很大½E‹åº¦ä¸Šæä¾›äº†(ji¨£n)一个容易集æˆçš„ç‰ÒŽ(gu¨©)€?
说到˜q™é‡Œ,应该对jBPMçš„IOC介ç»çš„å·®ä¸å¤šäº?我自己在用JBoss IDM project[2]æ¥å®žçްjBPMçš„Identity moduleæ—?需è¦å¢žåŠ å¦‚ä¸‹çš„é…ç½®.
<jbpm-configuration>
<process-engine-context>
<jboss-idm-identity-session-factory jndi="java:/IdentitySessionFactory" />
</process-engine-context>
<transaction-context>
<jboss-idm-identity-session realm="realm://JBossIdentity" />
</transaction-context>
</jbpm-configuration>
于是,我需è¦å¢žåŠ ä»¥ä¸‹çš„¾cÀL¥å®Œæˆå¯¹è±¡çš„创建和实例åŒ? JbossIdmIdentitySessionFactoryBinding,JbossIdmIdentitySessionFactoryDescriptor,JbossIdmIdentitySessionBinding, JbossIdmIdentitySessionDescriptor ç„¶åŽ,åœ?span class="emphasis">jbpm.wire.bindings.xmlé‡Œé¢æ³¨å†Œæˆ‘ä»¬æ–°åŠ çš„Binding. ä»Žä¸Šé¢æˆ‘们所说的,ä¸éš¾çœ‹å‡ºæœ¬èín˜q™ä¸ªIOC的实现机制也是很½Ž€å•çš„,而且也很å®ÒŽ(gu¨©)˜“扩展,如果说到时候和Spring, JBoss MC½{‰IOC容器的集æˆä¹Ÿæ˜¯å¾ˆæ–¹ä¾¿çš?
˜q™é‡Œ,我们看下jBPM-PVM概念和架æž?˜q™ä¹Ÿæ˜¯jBPM整个™å¹ç›®çš„æ ¸å¿?j¨©)所åœ?
Environment 的概å¿?ä¸»è¦æœ‰ä»¥ä¸‹çš„作用.
public abstract <T> T get(Class<T> type);
/** searches an object based on type. The search doesn take superclasses of the context elements
* into account.
* @return the first object of the given type or null in case no such element was found.
*/
public abstract <T> T get(Class<T> type, String[] searchOrder);
public interface RepositoryService {
NewDeployment createDeployment();
ProcessDefinitionQuery createProcessDefinitionQuery();
...
}
ExecutionService的一些方�
public interface ExecutionService {
ProcessInstance startProcessInstanceById(String processDefinitionId);
ProcessInstance signalExecutionById(String executionId);
...
}
public interface ManagementService {
void executeJob(long jobDbid);
JobQuery createJobQuery();
}
Command 概念的引å…?ä¸»è¦æ˜¯æƒ³å¯ÒŽ(gu¨©)‰€æœ‰çš„æ“ä½œåšä¸€ä¸ªå°è£? å¯ä»¥è¯´ä¸Šé¢æ¯ä¸ªService的方法的实现都是通过实现一个Commandæ¥æ“ä½?ç„¶åŽé€šè¿‡CommandService调用到åŽé¢å…·ä½“的实现. 我们先æ¥çœ‹ä¸‹Command的接å?
public interface Command<T> extends Serializable {
T execute(Environment environment) throws Exception;
}
很简å?很典型的Command模å¼.
public interface CommandService {
/**
* @throws JbpmException if command throws an exception.
*/
<T> T execute(Command<T> command);
}
CommandService ˜q˜æœ‰ä¸€ä¸ªç‰¹æ€?ž®±æ˜¯å¯ä»¥é…ç½®Interceptor,比如事务ž®±æ˜¯åœ¨è¿™ä¸€Service䏿¥é…ç½®.看下CommandService的酾|?
<command-service>
<retry-interceptor />
<environment-interceptor />
<standard-transaction-interceptor />
</command-service>
我们先看下ActivityBehaviour的接å?
public interface ActivityBehaviour extends Serializable {
void execute(ActivityExecution execution) throws Exception;
}
public interface ExternalActivityBehaviour extends ActivityBehaviour {
//handles an external trigger.
void signal(ActivityExecution execution, String signalName, Map<String, ?> parameters) throws Exception;
}
public interface Transition extends ObservableElement {
/** the activity from which this transition leaves. */
Activity getSource();
/** the activity in which this transition arrives. */
Activity getDestination();
}
在pvmä¸?也包括了(ji¨£n)对event的支æŒ?event的接å£å¦‚ä¸?
public interface EventListener extends Serializable {
void notify(EventListenerExecution execution) throws Exception;
}
ClientProcessDefinition definition = ProcessDefinitionBuilder.startProcess("jeffProcess")
.startActivity("initial", new AutomaticActivity())
.initial()
.transition("first")
.endActivity()
.startActivity("first", new WaitStateActivity())
.transition("end", "endSignal")
.endActivity()
.startActivity("end", new AutomaticActivity())
.endActivity()
.endProcess();
我们最åŽä»Žæ•´ä½“上æ¥çœ‹ä¸‹˜q™äº›API之间的蔾p?我觉得Developer Guide上的˜q™ä¸ªå›„¡‰‡å¾ˆæ¸…楚的æè¿°äº?ji¨£n)他的架构æ€èµ\.
˜q™é‡Œéœ€è¦æ³¨æ„çš„æ˜?本èínPVM内部的浽E‹å®šä¹‰æ¨¡åž‹æ˜¯POJOçš?æ‰€ä»¥å¦‚æžœä½ åªæ˜¯æƒÏxµ‹è¯•æµ½E‹çš„æ£ç¡®æ€?ä½ åªéœ€è¦ç›´æŽ¥ä‹É用Clientçš„API,比如ClientProcessDefinition, ClientProcessInstance½{‰çš„API.
ä¸éœ€è¦åŽ»è°ƒç”¨RepositoryService, ProcessEngineService. ˜q™äº›Serviceæ˜¯é’ˆå¯¹ä½ æŠŠProcessDefinition在ä¿å˜åœ¨æ•°æ®åº“的情况下æ‰éœ€è¦ç”¨çš?
˜q™é‡Œ,我们ž®†åˆ©ç”¨PVM所æä¾›çš„Model,æ¥å®žçŽîC¸€ä¸ªåŸºæœ¬çš„工作‹¹å¼•æ“?
public interface ActivityBehaviour extends Serializable {
void execute(ActivityExecution execution) throws Exception;
}
public class Display implements ActivityBehaviour {
String message;
public Display(String message) {
this.message = message;
}
public void execute(ActivityExecution execution) {
System.out.println(message);
}
}
我们先用˜q™ä¸ªDisplay,æ¥åˆ›å»ÞZ¸‹é¢çš„process.
ClientProcessDefinition processDefinition = ProcessDefinitionBuilder.startProcess("helloworld")
.startActivity("a", new Display("Hello"))
.initial()
.transition("b")
.endActivity()
.startActivity("b", new Display("World"))
.endActivity()
.endProcess();
processDefinition.startProcessInstance();
ž®×ƒ¼š(x¨¬)得到如下的结æž?
Hello
World
我们˜q™ä¸ªDisplay的节点就是采用的éšå¼execution执行æ–ÒŽ(gu¨©)³•.
public interface ExternalActivityBehaviour extends ActivityBehaviour {
//handles an external trigger.
void signal(ActivityExecution execution, String signalName, Map<String, ?> parameters) throws Exception;
}
我们接下æ¥å®žçŽîC¸€ä¸ªç®€å•çš„WaitState,实现ExternalActivityBehaviour的接å?
public class WaitState implements ExternalActivityBehaviour {
public void execute(ActivityExecution execution) {
execution.waitForSignal();
}
public void signal(ActivityExecution execution,
String signalName,
Map<String, Object> parameters) {
execution.take(signalName);
}
}
ClientProcessDefinition pd = ProcessDefinitionBuilder.startProcess("helloworld")
.startActivity("a", new WaitState())
.initial()
.transition("b", "b-transition")
.endActivity()
.startActivity("b", new WaitState())
.endActivity()
.endProcess();
ClientProcessInstance instance = pd.startProcessInstance();
instance.isActive("a")
instance.signal("b-transition");
instance.isActive("b")
接下æ?我们åŸÞZºŽå‰é¢ä¸¤ç§èŠ‚ç‚¹çš„å®žçŽ?æ¥å®žçŽîC¸€ä¸ªç¨å¾®æ¯”较æ£å¼çš„‹¹ç¨‹(loan process).
ClientProcessDefinition pd = ProcessDefinitionBuilder.startProcess("loanprocess")
.startActivity("submit loan request", new Display("submit a loan request"))
.initial()
.transition("evaluate", "evaluate-transition")
.endActivity()
.startActivity("evaluate", new WaitState())
.transition("wiremoney", "approve")
.transition("end", "reject")
.endActivity()
.startActivity("wiremoney", new Display("wire the money"))
.transition("archive")
.endActivity()
.startActivity("archive", new WaitState())
.transition("end", "done")
.endActivity()
.startActivity("end", new WaitState())
.endActivity()
.endProcess();
instance = pd.startProcessInstance();
instance.signal("approve");
instance.signal("done");
˜q™æ ·çš„è¯,整个‹¹ç¨‹ž®×ƒ¼š(x¨¬)èµ°å‘äº?ji¨£n)end节点.
事äšg的订阅å¯ä»¥é€šè¿‡å®žçްEventListeneræ¥å®žçŽ?
public interface EventListener extends Serializable {
void notify(EventListenerExecution execution) throws Exception;
}
具体的Event是由ObservableElementå’?span class="emphasis">EventNameæ¥æž„æˆçš„.
public interface EventListenerExecution extends OpenExecution {
void fire(String eventName, ObservableElement eventSource);
}
我们æ¥å®žçŽîC¸€ä¸ªç®€å•çš„EventListener, å«PrintLn
public class PrintLn implements EventListener {
String message;
public PrintLn(String message) {
this.message = message;
}
public void notify(EventListenerExecution execution) throws Exception {
System.out.println(message);
}
}
我们看下是怎么æ¥å®šä¹‰ä¸€ä¸ªå…·å¤‡æœ‰Eventsçš„ProcessDefinition:
ClientProcessDefinition pd = ProcessDefinitionBuilder.startProcess("ab")
.startActivity("a", new Display("Testing Event"))
.initial()
.transition("b")
.startEvent(Event.END)
.listener(new PrintLn("leaving a"))
.listener(new PrintLn("second message while leaving a"))
.endEvent()
.startEvent(Event.TAKE)
.listener(new PrintLn("taking transition"))
.endEvent()
.endActivity()
.startActivity("b", new WaitState())
.startEvent(Event.START)
.listener(new PrintLn("entering b"))
.endEvent()
.endActivity()
.endProcess();
我们å¯ä»¥çœ‹åˆ°,一个事件å¯ä»¥æœ‰æ— 穷多个的Listener(s).
è‡Ïx¤,我们主è¦çœ‹äº†(ji¨£n)PVM里é¢å†…部Model的一些设è®?ä¸€äº›æ ¸å¿?j¨©)的概念和API.
jBPM3 vs jBPM4
JBoss Goup ç›®å‰å·²ç»å‘布äº?/span> jBPM4 Alpha1 版本åQŒåœ¨ç‰ˆæœ¬ 4 䏿œ€å¤§çš„å˜åŒ–ž®±æ˜¯å¼•å…¥ PVM åQˆæµ½E‹è™šæ‹ŸæœºåQ‰çš„æ¦‚念åQŒè€Œå¼•擎内部的调度½Ž—法ä¸é‡è¦çš„ Token 机制åQŒåœ¨æ–°ç‰ˆä¸ä¹ŸåŽÀLމäº?ji¨£n),¾Uµè§‚整个代ç åQŒå˜åŒ–å¯ä»¥è¯´éžå¸¸çš„大åQŒç¬”者接下楞®Þp¯•ç€æ¥æ¯”较一下这¿Uå˜åŒ–,让大家能有个直观的认识。当ç„?/span> Jbpm4 åœ?/span> JBoss 的官方网站上çš?/span> Road map ä¸ï¼Œåœ¨ä»Šòq´çš„ 7 æœ?/span> 1 åäh‰ä¼?x¨¬)å‘布第一个æ£å¼ç‰ˆæœ¬ï¼Œå› æ¤åŽç®‹å¯èƒ½˜q˜ä¼š(x¨¬)有å˜åŒ–ã€?/span>
1ã€?/span>  ‹¹ç¨‹å®šä¹‰å¯¹è±¡çš„å˜åŒ–:(x¨¬)
Jbpm3 ‹¹ç¨‹å®šä¹‰å¯¹è±¡å…³ç³»å›¾ï¼š(x¨¬)
图一 jbpm3‹¹ç¨‹å®šä¹‰å¯¹è±¡å…³ç³»å›?/span>
Â
从上图我们å¯ä»¥çœ‹å‡?gu¨®)™¿?/span> jbpm3 ä¸ï¼Œ GraphElement 是浽E‹å›¾ä¸æ‰€æœ‰æµ½E‹å…ƒç´ 的父对象,而整个浽E‹æ˜¯ç”?/span> ProcessDefinition ã€?/span> Node ã€?/span> Transition 三个主è¦å¯¹è±¡æž„æˆåQ?/span>
Â
 图二 PVM实体对象关系å›?/span>     Â
Â
Â
从上囑֯以看出,ç”׃ºŽ PVM 概念的引入,所以在 jbpm3 ä¸çš„ Graph 包在 jbpm4 ä¸è¢«¿U»é™¤äº?ji¨£n)。在 pvm ä¸ï¼Œåœ¨è®¾è®¡æœŸåQŒæ‰€æœ‰èŠ‚ç‚¹å…ƒç´ çš„çˆ¶ç±»ä¸?/span> ProcessElementImpl åQŒæµ½E‹çš„主覾l„æˆå…ƒç´ Nodelmpl ã€?/span> TransitionImpl ã€?/span> ProcessDefinitionImpl ã€?/span> EventImpl 则都直接或间接ç‘ô承自 ProcessElementImpl 。在˜q行期:(x¨¬) jbpm4 把浽E‹çš„˜qè¡ŒæœŸè¡Œä¸ºå®šä¹‰äØ“(f¨´)æ‰§è¡Œè¡ŒäØ“(f¨´)åQ?/span> ExecutionImpl åQ‰åŠ(qi¨¢ng)åŽŸåæ“ä½œè¡ŒäØ“(f¨´)åQ?/span> AtomicOperation åQŒå…¶å…·ä½“实现ä¸?/span> ExecuteNode ã€?/span> ProceedToDestination ã€?/span> TakeTranstion ã€?/span> MoveToParentNode ã€?/span> MoveToChildNode ã€?/span> signal åQ‰ï¼Œå…¶ä¸ ExecutionImpl 是浽E‹å®žä¾‹ã€æ´»åŠ¨å®žä¾‹ã€äº‹ä»¶ç›‘å¬å™¨çš„æ‰€æœ‰æ‰§è¡ŒæœŸè¡ŒäØ“(f¨´)的实现类ã€?/span>
Â
图三 jpdl ˜q行期活动实体对象关¾pÕd›¾
 上图æ˜?/span> jbpm4 在è¿è¡ŒæœŸçš„æ´»åŠ¨å®žä¾‹å¯¹è±¡å…³¾pÕd›¾åQŒä»Žå›¾ä¸æˆ‘们å¯ä»¥çœ‹å‡ºåQŒåœ¨˜q行期, jbpm4 ä¸å®šä¹‰äº†(ji¨£n)两个‹zÕdŠ¨æŽ¥å£ Activity å’?/span> ExternalActivity åQŒå…¶ä¸?/span> ExternalActivity ¾l§æ‰¿è‡?/span> Activity ã€?/span> Activity 是所有自动活动节点的父接å£ï¼Œå…¶å®žçŽ°ç±»ä¸?/span> JpdlActivity åQŒè€?/span> JpdlActivity åˆè¡ç”Ÿå‡ºäº?ji¨£n)ã€?/span> StartActivity ã€?/span> JoinActivity ã€?/span> ForkActivity ã€?/span> EndActivity ã€?/span> CreateTimerActivity ã€?/span> JavaActivity ã€?/span> EsbActivity ½{‰å®žä¾‹æ´»åŠ¨å¯¹è±¡ã€‚è€?/span> ExternalActivity 是具有ç‰å¾…状æ€çš„‹zÕdЍåQ?/span> StateActivity åQ‰çˆ¶æŽ¥å£åQŒåƒäººå·¥‹zÕdЍ TaskActivity ž®±æ˜¯å®žçްäº?ji¨£n)æ¤æŽ¥å£ã€?/span>
 2ã€?/span> Â æ ¸å¿ƒ(j¨©)引擎的调度算æ³?/span>
Jbpm3 çš„æ ¸å¿?j¨©)调度算法是åŸÞZºŽ Token 机制的,在è¿è¡ŒæœŸ˜q™ä¸ª Token åœ?/span> Node Instance 之间‹¹è{åQŒä¾é?/span> Token çš„è§¦å‘æ¥æŽ¨è¿›‹¹ç¨‹ã€‚具体的调度机制åQŒå¯å‚åŠ èƒ¡é•¿åŸŽçš„æ–‡ç« åQ?/span> http://blog.csdn.net/james999/archive/2007/09/02/1769592.aspx åQ‰ï¼›å…¶å®ž˜q™ä¸ª Token æ¥è‡ªäº?/span> Pertri-net åQŒæ„Ÿå…´è¶£çš„读者å¯ä»¥åŽ»çœ?/span> Pertri-net ä¸çš„ Token å?/span> Place ã€?/span>
Â
囑֛› jbpm3引擎调度å›?/span> Â
Jbpm4 则去掉了(ji¨£n) Token åQŒé‚£ä¹ˆå®ƒçš„æ ¸å¿?j¨©)è°ƒåº¦æœºåˆ¶æ˜¯æ€Žæ ·å®žçŽ°çš„å‘¢åQ?/span>
 图五 jbpm4‹¹ç¨‹å¯åЍåºåˆ—å›?/span>
囑օ jbpm4 ‹¹ç¨‹æŽ¨è¿›åºåˆ—å›?/span>
图五是在 jbpm4 ä¸å¯åŠ¨ä¸€ä¸ªæµ½E‹å®žä¾‹çš„æ‰§è¡Œåºåˆ—图,囑օ是节ç‚ÒŽ(gu¨©)ލ˜q›çš„æ‰§è¡Œåºåˆ—图,从上é¢ä¸¤ä¸ªå›¾ä¸æˆ‘们å¯ä»¥çœ‹åˆ°æ ¸å¿?j¨©)çš„è°ƒåº¦æ˜¯ä¾æ?/span> Execution çš„è{¿UÀL¥å®žçŽ°çš„ï¼ˆ ExecutionImpl å¯ä»¥æ˜?/span> ActivityExecution ã€?/span> ClientProcessInstance ã€?/span> EventListenerExecution 的实例)(j¨ª)åQ?/span> Execution 实际上就是å–代了(ji¨£n) Jbpm3 ä¸çš„ Token åQ?/span> Execution çš„è{¿UÕd®žé™…上ž®±æ˜¯æ ÒŽ(gu¨©)®çŠ¶æ€æœºçš„嘘q( ActivityExecution ã€?/span> ClientProcessInstance ã€?/span> EventListenerExecution 实例之间的切æ¢ï¼‰(j¨ª)åŠ ä¸Šè°ƒç”¨ç›¸åº”çš„åŽŸåæ“ä½œï¼š(x¨¬) ExecuteNode ã€?/span> MoveToChildNode ã€?/span> MoveToParentNode ã€?/span> ProceedToDesitination ã€?/span> Signal ã€?/span> TakeTransition åQˆè¯¦è§?/span> pvm/internal/model/op 包下的相关类åQ‰æ¥å®žçŽ°çš„ã€‚æ‰€ä»?/span> Execution 实例的集åˆåŠ(qi¨¢ng)有å‘囑֮žé™…上ž®±æ˜¯˜q行期的路径ã€?/span>
Â
3ã€?/span>  Event-Action 机制的å˜åŒ?/span>
åœ?/span> jbpm3 䏿˜¯åŸÞZºŽ Event-Action 机制æ¥å®žçŽîCº‹ä»¶ä¸ŽåŠ¨ä½œçš„è§¦å‘çš„åQŒä½†æ˜¯åœ¨ jbpm4 ä¸åˆ™é‡‡ç”¨è§‚å¯Ÿè€…æ¨¡å¼æ¥è§¦å‘事äšg的。所有用戯‚‡ªå·±å®šä¹‰çš„动作åQŒå…¨éƒ¨è¦å®žçް EventListener 接å£åQŒè¿™äº›åŠ¨ä½œä½œä¸ºç›‘å¬è€…(ž®±æ˜¯äº‹äšg Event 的观察è€?/span> Observer åQ‰æ³¨å†Œåˆ°ç›¸åº”的浽E‹å®šä¹‰å¯¹è±¡ä¸ŠåQ?/span> ProcessElement 或è€?/span> Node åQ‰ï¼Œè€Œäº‹ä»?/span> Event åˆ™ä½œä¸ø™¢«è§‚察的对象(实际上就æ˜?/span> Observerable åQ‰ï¼Œå®žé™…上在 jbpm4 ä¸ä¸“门定义出äº?ji¨£n)一个对è±?/span> ObservableElementImpl åQŒæµ½E‹å®šä¹‰ä¸çš?/span> NodeImpl ã€?/span> TransitionImpl ã€?/span> ProcessDefinitionImpl å‡ç‘ô承自æ¤å¯¹è±¡ï¼Œå› 椘q™äº›å…ƒç´ 本èínž®±å¯ä»¥ä½œä¸?/span> Observerable 而被观察者æ¥ç›‘控ã€?/span>
4ã€?/span>  客户端接å£çš„å˜åŒ–
åœ?/span> jbpm4 ä¸å¯¹å®¢æˆ·ç«¯çš„æŽ¥å£¾lŸä¸€ä¸?/span> 7 个æœåŠ¡æŽ¥å£ï¼š(x¨¬) ProcessService ã€?/span> ExecutionService ã€?/span> CommandService ã€?/span> TaskService ã€?/span> ManagementService ã€?/span> HistoryService ã€?/span> IdentityService åQŒè¿™ 7 个接å£å¯ä»¥ä»Ž ProcessEngine 接å£ä¸èŽ·å¾—ï¼Œ jbpm4 在å¯åŠ¨çš„˜q‡ç¨‹ä¸ç”± JbpmConfiguration 负责构å¾å¼•擎ã€?/span>
Ø ProcessService- ‹¹ç¨‹å®šä¹‰çš„æœåŠ¡æŽ¥å£ï¼ŒåŒ…括å¯ÒŽ(gu¨©)µ½E‹å®šä¹‰çš„部çÖvã€æŸ¥è¯¢ã€åˆ 除æ“作;
Ø ExecutionService- 执行æœåŠ¡æŽ¥å£åQŒåŒ…括å¯åŠ¨æµ½E‹ã€å®žä¾‹æŽ¨˜q›ã€è®¾¾|®å˜é‡ç‰æ“作åQ?/span>
Ø CommandService-Command 模å¼çš„æœåŠ¡æŽ¥å£ï¼Œå®žé™…上就是将客户端的è¯äh±‚全部ž®è£…在一个调用接å£ä¸åQŒç„¶åŽç”±˜q™ä¸ªæŽ¥å£åŽ»è°ƒç”?/span> Command 接å£çš„众多实玎ͼˆ StartExecutionCmd ã€?/span> SignalCmd ã€?/span> SetVariablesCmd ã€?/span> GetTimersCmd ã€?/span> DeployCmd ã€?/span> NewTaskCmd ã€?/span> SubmitTask ã€?/span> ExecuteJobCmd ½{‰ç‰åQŒå…·ä½“å¯å‚åŠ pvm/internal/cmd åQ?/span> task/internal/cmd 包åŠ(qi¨¢ng)其它包下实现 Command 接å£çš„ç±»åQ‰ï¼Œ˜q™æ˜¯å…¸åž‹çš?/span> Command 模å¼çš„应用,感兴‘£çš„读者å¯ä»¥åŽ»äº?ji¨£n)解设计模å¼ä¸çš?/span> Command 模å¼åQ?/span>
Ø TaskService- 人工‹zÕdŠ¨çš„æœåŠ¡æŽ¥å£ï¼ŒåŒ…括对ä“Q务的创å¾ã€æäº¤ã€æŸ¥è¯¢ã€ä¿å˜ã€åˆ é™¤ç‰æ“作åQ?/span>
Ø ManagementService-web ½Ž¡ç†æŽ§åˆ¶å°çš„æœåŠ¡æŽ¥å£åQŒç›®å‰åªæœ‰èŽ·å¾—æ¶ˆæ¯åŠ(qi¨¢ng)计时器的接å£å®žçްåQ?/span>
Ø HistoryService- ç›®å‰æœ‰å¯¹åކå²åº“ä¸çš„æµ½E‹å®žä¾‹ã€æ´»åŠ¨å®žä¾‹è¿›è¡ŒæŸ¥è¯¢ã€æŸä¸ªæµ½E‹å®šä¹‰ä¸çš„æ‰€æœ‰æ´»åŠ¨çš„òq›_‡æŒç®‹æ—‰™—´ã€æŸä¸ªæµ½E‹å®šä¹‰ä¸çš„æŸä¸ªæ´»åŠ¨å®žä¾‹çš„è½¬ç§»çš„æ‰§è¡Œæ¬¡æ•?/span>
Ø IdentityService- 用户ã€ç»„ã€æˆå‘˜å…³¾pÈš„相关æ“作æ–ÒŽ(gu¨©)³•
Â
5ã€?span style="font-family: "Times New Roman"; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"> 历å²åº“çš„åŠ å…¥
jBPM3 䏿•°æ®åº“设计一直是我比较诟病的地方åQŒå°¤å…¶æ˜¯å…¶å®žä¾‹æ•°æ®åº“没有设计历å²åº“的概念òq¶æŒ‰ç…§åŠž¾l“状æ€å°†˜q行¾l“æŸçš„实例数æ®å½’入历å²åº“åQŒåœ¨˜q™ç§æƒ…况下它的实例数æ®åº“ž®×ƒ¼š(x¨¬)éšç€æ—‰™—´è€Œæ— é™è†¨èƒ€åQŒè¿™ž®±é˜»¼„了(ji¨£n)它的真实应用åQŒè€Œåœ¨ jBPM4 的最æ–îC»£ç ä¸åQˆæ³¨æ„?/span> Alpha1 ˜q˜æ²¡æœ‰å‡ºçŽŽÍ¼‰(j¨ª)åQŒåކå²åº“的相兛_ŠŸèƒ½ä»£ç 竟然出çŽîCº†(ji¨£n)åQ详è§?/span> ExecutionImpl 最æ–îC»£ç ä¸çš?/span> fireHistoryEvent æ–ÒŽ(gu¨©)³•å?qi¨¢ng)一¾pÕdˆ—çš?/span> historyXXX æ–ÒŽ(gu¨©)³•。在 ActivityBehaviour çš?/span> execute æ–ÒŽ(gu¨©)³•ä¸åŠ å…¥äº†(ji¨£n) historyTaskStart æ–ÒŽ(gu¨©)³•的调用ã€?/span> signal æ–ÒŽ(gu¨©)³•ä¸åŠ å…¥äº†(ji¨£n) historyTaskEnd æ–ÒŽ(gu¨©)³•的调用,而以ä¸?/span> 2 个方法在 ExecutionImpl ä¸éƒ½æ˜¯ä»¥åކå²äº‹äšgåQ?/span> HistoryEvent æœ?/span> 4 个实现å¾c?/span> ProcessInstanceStart ã€?/span> ProcessInstanceEnd ã€?/span> ActivityStart ã€?/span> ActivityEnd 分别用作‹¹ç¨‹å®žä¾‹çš„åˆ›å»ºç»“æŸæœŸã€æ´»åŠ¨å®žä¾‹çš„åˆ›å¾¾l“æŸæœŸçš„åŽ†å²æ•°æ®å¤„ç†åQ‰çš„è§¦å‘æœºåˆ¶æ¥å®žçŽ°çš„åQŒä¹Ÿž®±æ˜¯åœ¨æ•´ä¸ªæµ½E‹å®žä¾‹æ‰§è¡Œçš„˜q‡ç¨‹ä¸ï¼Œéƒ½åŠ å…¥äº†(ji¨£n)对将˜q行数æ®å˜å…¥åކå²åº“的历å²äº‹äšgåQ?/span> HistoryEvent åQ‰çš„触å‘ã€‚è¿™æ ·å®žä¾‹åˆ—è¡¨çš„æŸ¥è¯¢å¯ä»¥åªæŸ¥è¯¢åކå²åº“。丘q‡è¿™é‡Œå¾ˆé—憾的是åQŒè¿™ä¸ªäº‹ä»¶æ²¡æœ‰åŒæ—¶æ¸…除è¿è¡Œåº“的数æ®ï¼Œ˜q™æ ·˜q˜æ˜¯ä¼?x¨¬)é€ æˆ˜qè¡Œåº“çš„æ— é™è†¨èƒ€é—®é¢˜ã€?/span>