ï»??xml version="1.0" encoding="utf-8" standalone="yes"?>亚洲精品一级二级三级,亚洲综合一区在线,精品视频一区二区三区四区http://www.aygfsteel.com/libin2722/category/40764.html虚其å¿?j¨©),可解天下之问åQ›ä¸“其心(j¨©)åQŒå¯æ²Õd¤©ä¸‹ä¹‹å­¦ï¼›é?r¨´n)其心(j¨©),可æ‚(zh¨¨n)Ÿå¤©ä¸‹ä¹‹ç†åQ›æ’其心(j¨©)åQŒå¯æˆå¤©ä¸‹ä¹‹ä¸šã€?/description>zh-cnTue, 14 Jul 2009 17:03:01 GMTTue, 14 Jul 2009 17:03:01 GMT60jBPM 4.0 解读分析http://www.aygfsteel.com/libin2722/articles/286675.html½C¼ç‰©½C¼ç‰©Tue, 14 Jul 2009 05:15:00 GMThttp://www.aygfsteel.com/libin2722/articles/286675.htmlhttp://www.aygfsteel.com/libin2722/comments/286675.htmlhttp://www.aygfsteel.com/libin2722/articles/286675.html#Feedback0http://www.aygfsteel.com/libin2722/comments/commentRss/286675.htmlhttp://www.aygfsteel.com/libin2722/services/trackbacks/286675.html
Revision History
Revision 0.1 2009/06/29
增加äº?ji¨£n)å‰?章的内容

Abstract

˜q™ç¯‡æ–‡ç« ä¸»è¦æ˜¯ä»‹¾läº†(ji¨£n)jBPM 4.0的基¼‹€æž¶æž„,以及(qi¨¢ng)通过一个简单的例子来让大家知道怎么应用jBPM. ä¸ÞZ»€ä¹ˆé€‰æ‹©4.0版本å‘?以后的主‹¹ç‰ˆæœ¬åº”该是4.0版本çš?所以直接写4.0版本的了(ji¨£n).

在默认情况下,jBPM包里有个jbpm.cfg.xml,˜q™ä¸ªž®±æ˜¯ä»–的配置文äšg,我们先看下它的内å®?

												
														
<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>

˜q™é‡Œ,我们再ç‘ô¾l­çœ‹ä¸?span class="emphasis">jbpm.default.cfg.xml,看下配置文äšg到底是长啥样.

												
														
<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'的配¾|?

我们知道,现在都是讲究Dependency Inject (Inversion of Control),那么,我们˜q™é‡Œåˆ°åº•是哪个类来实现repository-serviceå‘?那配¾|®mail-session又是怎么实例化的å‘? 我们先来看下jBPMçš„IOC实现机制.

首先æ˜?span class="emphasis">Context接口,你可以从˜q™é‡Œå­˜å‚¨,获得对象.它的接口很简å?

												  Object get(String key);
<T> T get(Class<T> type);

Object set(String key, Object value);

你看可以从Context中获取到¾l„äšg,对于IOC容器来说åQŒä¸€èˆ¬æƒ…况下都会(x¨¬)提供一¿UåŠ è½½çš„æ–¹å¼åQŒæ¯”如从xmlæ–‡äšg˜q›è¡ŒåŠ è²ã€ä»Žèµ„æºæ–‡äšg˜q›è¡ŒåŠ è²ã€?

Jbpm4是通过WireParser来解析xml,然后创徏òq¶æŠŠå¯¹è±¡å­˜æ”¾åœ?span class="emphasis">WireContext. WireContext˜q™ä¸ª¾c»è´Ÿè´£å­˜æ”?提取对象,内部用一个Map来存储已¾låˆ›å»ºçš„对象实例,可以½Ž€å•得把他看成是IOC的一个实现类. ä»?span class="emphasis">WireContextçš„javadoc,我们可以看出,他主要是è·?span class="emphasis">WireDefinition, Descriptoræ‰? 交道. WireContext里面 包含äº?ji¨£n)一个WireDefinition,而W(xu¨¦)ireDefinition里面包含äº?ji¨£n)一¾pÕdˆ—çš„Descriptor.每个Descriptor负责创徏å’? 初始化该对象. 比如我们可以看到IntegerDescriptor, FloatDescriptor, ObjectDescriptor½{‰ç­‰. 我们来看下Descriptor的接å?

												
														
/**
* 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);

Descriptor对象的创建可以直接通过Java对象的实例化,比如(new IntegerDescriptor(..)),也可以通过xml的配¾|®æ–‡ä»¶æ¥å®žçް.可以说我们更¾lå¸¸ç”¨xml来配¾|?所以就有了(ji¨£n)Binding的概å¿? Binding¾cÀLœ€ä¸»è¦çš„ä“Q务就是把XML DOM 到Java对象的è{æ? Bindings是把Bindingå½’ç±»äº?ji¨£n)一下而已. 以下是Binding的接å?

												
														
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);
}

如果想看实现,我们可以看下IdentityServiceBinding, RepositoryServiceBinding½{‰ç­‰.˜q™é‡Œæ³¨æ„ä¸?在jBPM的实现当ä¸?WireDescriptorBinding是根据tagName来解析的. 所ä»?从jBPMçš„xml配置文äšg,到ProcessEngine对象的构å»?是这æ ïL(f¨¥ng)š„一个流½E?

												 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¨©)所åœ?

PVM (Process Virtual Machine), ä¸»è¦æ˜¯æƒ³ä½œäØ“(f¨´)一个开发åã^å?在这个åã^åîC¸Š,可以很方便的开发工作流,服务¾~–制(orchestration),BPM½{‰ç­‰.ž®±æ¯”å¦? 说jPDL˜q™å¥—语法的内部实现就是基于PVMçš?ž®†æ¥åŸÞZºŽPVM可以开发一个符合WS-BPEL 2.0的模å? PVM可以½Ž€å•的看成是一个状态机. 我们接下åŽÈœ‹ä¸‹jBPM里面的几个重要概å¿?

Environment 的概�主要有以下的作用.

在代码中,我们惌™Ž·å¾—å…¶ä»–çš„¾l„äšgæ—?或者变量时,我们æ€ÀL˜¯ä½¿ç”¨Environmentçš„API, 我们可以看下它的API的几个重要方æ³?

														   	  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);

Environment 内部是ä‹É用Map来保存不同的Context对象, Environment对象的创å»ÞZ¸»è¦æ˜¯æœ?span class="emphasis">EnvironmentFactory来负è´? Environment是被保存在ThreadLocalä¸?如果有多个Environment,那么是选择把Environment(s)攑֜¨ä¸€ä¸ªå †æ ˆä¸­,然后再存攑֜¨ThreadLocalé‡?

Command 概念的引å…?主要是想å¯ÒŽ(gu¨©)‰€æœ‰çš„æ“ä½œåšä¸€ä¸ªå°è£? 可以说上面每个Service的方法的实现都是通过实现一个Command来操ä½?然后通过CommandService调用到后面具体的实现. 我们先来看下Command的接å?

														public interface Command<T> extends Serializable {
T execute(Environment environment) throws Exception;
}

很简�很典型的Command模式.

我们接下来看CommandService接口,™å‘֐æ€ä¹‰,他主要是负责来执行Command(s)的操ä½?所以其他Service的实现都是通过CommandService来调用到后面的实çŽ?可以把CommandService 看做一个桥梁的作用.看一下CommandService的接å?

														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>

˜q™é‡Œ,在执行真正的CommandServiceImpl之前,ä¼?x¨¬)先之前retry-Interceptor,environment-interceptor½{‰ç­‰.˜q™é‡Œçš„Interceptor的顺序是跟配¾|®çš„™åºåºä¸€è‡´çš„. 比如˜q™æ ·çš„配¾|?那就是retry-interceptor在environment-interceptor之前执行. 我们看下面这个图.

ProcessDefinition是一个定义好的工作流½E? OpenProcessDefinition里面包含äº?ji¨£n)启始的Activity. ‹¹ç¨‹çš„走向是通过Activity的流向来¾l„成çš? Transitionž®±æ˜¯ç”¨æ¥˜qžæŽ¥Activity而后来构成一个流½E‹çš„. 一个工作流的工作引æ“?最基本的两个功èƒ?一个是设计好当前的工作‹¹ç¨‹.½W¬äºŒä¸ªæ˜¯æœ‰ä¸ªä¸œè¥¿éœ€è¦æ¥ä½“现当前走到‹¹ç¨‹çš„哪一æ­?那么PVM中的Execution APIž®±æ˜¯˜q™ä¸ªä½œç”¨. 至于最后一个Event,ž®±æ˜¯ä½ å¯ä»¥å®šä¹‰ä¸€äº›äº‹ä»?比如当流½E‹è¿›å…¥åˆ°æŸä¸€ä¸ªActivity的时å€?ä¿?j¨©)发email. Eventå’ŒActivity最大的区别在于Event本èín不会(x¨¬)构成å¯ÒŽ(gu¨©)µ½E‹èµ°å‘的改变.

我们先看下ActivityBehaviour的接�

														public interface ActivityBehaviour extends Serializable {
void execute(ActivityExecution execution) throws Exception;
}

ž®±æ˜¯åˆ°è¿™ä¸ªActivity,需要执行的操作都在executeæ–ÒŽ(gu¨©)³•é‡? ˜q˜æœ‰ä¸€¿UActivityBehaviour,ž®±æ˜¯å±žäºŽwait state,也就是会(x¨¬)停留在这个节点上, 需要外部的一些触å?才会(x¨¬)¾l§ç®‹æ‰§è¡Œä¸‹åŽ»,˜q™ç§æƒ…况,需要实现的接口ž®±æ˜¯ExternalActivityBehaviour, 接口如下.

														public interface ExternalActivityBehaviour extends ActivityBehaviour { 
//handles an external trigger.
void signal(ActivityExecution execution, String signalName, Map<String, ?> parameters) throws Exception;
}

Wait State (也就是实现ExternalActivityBehaviour)的促(j¨©)å?是通过Transition来完成的,来看下Transition˜q™ä¸ªæŽ¥å£.

														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;
}

如我们之前所说的, ProcessDefinition是由Activity,Transition以及(qi¨¢ng)Event¾l„成çš?ProcessDefinition是由ProcessDefinitionBuilder çš„API来创å»?我们½Eå¾®çœ‹ä¸‹˜q™ä¸ªAPIçš„ä‹Éç”?

																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™é‡Œ,我们ž®†åˆ©ç”¨PVM所提供的Model,来实çŽîC¸€ä¸ªåŸºæœ¬çš„工作‹¹å¼•æ“?

正如我们之前所说的,ActivityBehaviour是整个流½E‹çš„定义核心(j¨©)所åœ?我们再看下它的API.

														public interface ActivityBehaviour extends Serializable {    
void execute(ActivityExecution execution) throws Exception;
}

当之行到ActivityBehaviour的时å€?整个‹¹ç¨‹çš„走向完全是ç”׃»–çš„execute()æ–ÒŽ(gu¨©)³•来决å®? 比如你可以调用execution.end()来结束这个流½E?或者调用execution.waitForSignal()˜q›å…¥ä¸€ä¸ªç­‰å¾…状æ€? 我们接下åŽÀL¥å®žçŽ°ä¸€ä¸ªå¾ˆ½Ž€å•çš„ActivityBehaviour.

														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¨©)³•.

外部节点ž®±æ˜¯ä»£è¡¨ç€,˜q™ä¸ª‹zÕdЍ˜q˜éœ€è¦ç³»¾lŸå¤–部的配合,比如说äh工的配合才能使得˜q™ä¸ª‹¹ç¨‹¾l§ç®‹ä¸‹åŽ».我们一般称˜q™ç§çš„èŠ‚ç‚¹äØ“(f¨´) Wait State. 因䨓(f¨´)他需要一直等å¾?直至外部‹zÕdŠ¨çš„ä¿ƒ(j¨©)å?然后‹¹ç¨‹æ‰ç‘ô¾l? ˜q™ç§çš„节炚wœ€è¦å®žçްExternalActivityBehaviourçš„API.

														public interface ExternalActivityBehaviour extends ActivityBehaviour { 
//handles an external trigger.
void signal(ActivityExecution execution, String signalName, Map<String, ?> parameters) throws Exception;
}

跟内部节点类ä¼?执行到ExternalActivityBehaviour的时å€?也是执行它的execute()æ–ÒŽ(gu¨©)³•,但是一般来è¯?在外部活动的execute()æ–ÒŽ(gu¨©)³•ä¸? ä¼?x¨¬)调用execution.waitForSignal()æ–ÒŽ(gu¨©)³•,使得activity˜q›å…¥ä¸€ä¸ªç­‰å¾…状æ€? 直到外部调用signal()æ–ÒŽ(gu¨©)³•来ä‹É得流½E‹å†‹Æ¡ä»Ž½{‰å¾…状态变成激‹z?一般来说在signal()æ–ÒŽ(gu¨©)³•ä¸?ä¼?x¨¬)调用execution.take(signalName)æ ÒŽ(gu¨©)®signalName(也就是transition name)åŽÀL‰¾åˆ? 下一个节ç‚?然后把整个流½E‹èµ°åˆîC¸‹ä¸€ä¸ªèŠ‚ç‚?

很简单的一个例子是,比如说一个申请审批的‹¹ç¨‹,员工递交一份申请上åŽ?然后¾l§ç®‹ž®Þp¿›å…¥ä¸€ä¸ªwait state的状æ€?因䨓(f¨´)他需要经理的审批(也就是一个äh工的‹zÕdЍ),那么¾lç†å¯ä»¥é€‰æ‹©ä¸€ä¸ªokçš„signalName,使得整个 ‹¹ç¨‹˜q›å…¥åˆîC¸‹ä¸€ä¸ªèŠ‚ç‚?˜q™é‡Œž®±å¥½æ¯”如是结束的节点,又或者ä‹É得整个流½E‹ç›´æŽ¥ç»“æ?

我们接下来实çŽî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);
}
}

一æ ïL(f¨¥ng)š„,我们来看一个简单的从a->b的流½E?˜q™æ¬¡ä¸åŒçš„æ˜¯,aå’Œb都是wait state.


ProcessDefinition的定�

														ClientProcessDefinition pd = ProcessDefinitionBuilder.startProcess("helloworld")
.startActivity("a", new WaitState())
.initial()
.transition("b", "b-transition")
.endActivity()
.startActivity("b", new WaitState())
.endActivity()
.endProcess();

启动˜q™ä¸ªProcessDefinition

														ClientProcessInstance instance = pd.startProcessInstance();
instance.isActive("a")

在启动之å?因䨓(f¨´)执行到a的时å€?是一个wait state,所ä»?当前的流½E‹æ´»åŠ¨åº”è¯¥æ˜¯æŒ‡å‘a. 如果要到b˜q™ä¸ªactivity,那么ž®±éœ€è¦è°ƒç”?

														instance.signal("b-transition");
instance.isActive("b")

那么,ä½ å°±ä¼?x¨¬)发ç?¾lè¿‡æˆ‘们调用signalæ–ÒŽ(gu¨©)³•,instanceæ ÒŽ(gu¨©)®æ‰€æä¾›çš„transitionName (b-transition),扑ֈ°ä¸‹ä¸€ä¸ªèŠ‚ç‚?也就是b. 但因为b也是一个wait state,所以此åˆ?整个‹¹ç¨‹ž®±åœç•™åœ¨äº?ji¨£n)b节点íw«ä¸Š.

接下æ?我们åŸÞZºŽå‰é¢ä¸¤ç§èŠ‚ç‚¹çš„å®žçŽ?来实çŽîC¸€ä¸ªç¨å¾®æ¯”较正式的‹¹ç¨‹(loan process).


ProcessDefinition的定�

															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();

启动˜q™ä¸ªprocessInstance

														instance = pd.startProcessInstance();

启动˜q™ä¸ªprocessInstanceå?它开始点在submit loan request˜q™ä¸ªèŠ‚ç‚¹,后面¾lè¿‡Display˜q™ä¸ªèŠ‚ç‚¹,默认走到äº?ji¨£n)evaluate˜q™ä¸ªèŠ‚ç‚¹. 因䨓(f¨´)evaluate是个wait state,所以流½E‹åœåœ¨äº†(ji¨£n)evaluate.


现在å‘? evaluate˜q™ä¸ªèŠ‚ç‚¹æœ‰ä¸¤æ¡æ”¯è·?一个是approve,指向wiremoney节点;另外一个是reject,直接走向end. 假设我们选择approve˜q™æ¡æ”¯èµ\.

														instance.signal("approve");

那么,我们ž®Þpµ°å‘了(ji¨£n)wiremoney˜q™ä¸ªèŠ‚ç‚¹,因䨓(f¨´)wiremoney是个Display节点,所以它昄¡¤ºå®ŒåŽ,默认的走向下一个节ç‚?archive.


同样çš?因䨓(f¨´)archive节点是个wait state,所以需要再一‹Æ¡çš„signal,才能走到end˜q™ä¸ªèŠ‚ç‚¹.

														instance.signal("done");

˜q™æ ·çš„话,整个‹¹ç¨‹ž®×ƒ¼š(x¨¬)走向äº?ji¨£n)end节点.


事äšg的订阅可以通过实现EventListener来实çŽ?

														public interface EventListener extends Serializable {
void notify(EventListenerExecution execution) throws Exception;
}

Event概念的引å…?ä¸»è¦æ˜¯äØ“(f¨´)äº?ji¨£n)å×I补分析员(Business Analyst)和开发ähå‘?Developer)之间的不同需æ±? developer可以使用Event在一些节点上来做一些操ä½?比如说操作数据库),˜q™æ ·å‘?也不ä¼?x¨¬)åª?ji¨£ng)响整个流½E?所以分析员不用åŽÕd…³å¿?j¨©)这些具体的Event, 他们只需要看‹¹ç¨‹æ˜¯å¦è·Ÿä»–们所期望的是一致的.

具体的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.



]]>
jBPM4的运行期环境http://www.aygfsteel.com/libin2722/articles/286673.html½C¼ç‰©½C¼ç‰©Tue, 14 Jul 2009 05:13:00 GMThttp://www.aygfsteel.com/libin2722/articles/286673.htmlhttp://www.aygfsteel.com/libin2722/comments/286673.htmlhttp://www.aygfsteel.com/libin2722/articles/286673.html#Feedback0http://www.aygfsteel.com/libin2722/comments/commentRss/286673.htmlhttp://www.aygfsteel.com/libin2722/services/trackbacks/286673.html jBPM4的运行期环境         万物生长靠太阻I¼Œå„¿ç«¥çš„生长离不开土壤、空气和æ°ß_(d¨¢)¼Œå½“ç„¶åQŒä¹Ÿ¼›ÖM¸å¼€¾l¿åå¨˜çš„调教。应用程序也是如此,¼›ÖM¸å¼€æ•°æ®åº“连接、事务、日志、消息等åQŒè¿™äº›ï¼Œå…±åŒæž„成äº?ji¨£n)应用程序的˜qè¡ŒæœŸçŽ¯å¢ƒã€?br />         理想中的环境是什么样子的哩。好吧,一句话åQŒå¬ä¹‹å³æ¥ï¼ŒæŒ¥ä¹‹å›_Ž»åQŒå½“需要某个服务时åQŒokåQŒæ‰“个响指,该服务就准备好被调用äº?ji¨£n),调用完毕后也不用费å¿?j¨©)费力 地擦屁股åQŒä¸å¿…老是提心(j¨©)吊胆有好事者追问:(x¨¬)你擦äº?ji¨£n)吗åQŒç¡®å®šæ“¦äº?ji¨£n)?真的¼‹®å®šæ“¦äº?ji¨£n)åQŸç›´æŽ¥ä¸¢å¼ƒç»™çŽ¯å¢ƒé™è§£å¤„ç†åQŒè‡ªç„¶åˆçŽ¯ä¿åQŒè¿˜æœ‰ä¸ªå¥½åå£°å«ä¸“注领域逻辑ã€?br />
一、  Â?˜qè¡ŒæœŸçŽ¯å¢ƒå°±æ˜¯ä¸€ä¸ªé¤é¦?/strong>
1、  Â?提供必要的服åŠ?br /> ä½œäØ“(f¨´)ä¸€ä¸ªé¤é¦†ï¼Œå¿…é¡»æœ‰åŽ¨å¸ˆåšé¥­æˆ‘åƒï¼Œå¿…é¡»æœ‰æ¡Œå­å’Œæ¤…å­ã€‚ä½œä¸ø™¿è¡ŒæœŸçŽ¯å¢ƒåŒæ ·å¦‚æ­¤åQŒæˆ‘要发消息åQŒä½ å¾—提供我发消息的ServiceåQŒæˆ‘要获取节点ä“Q务,你得扔给我TaskServiceã€?br />
2、  Â?提供获取˜q™äº›æœåŠ¡çš„ç»Ÿä¸€æ–¹å¼
好吧åQŒæˆ‘不会(x¨¬)亲自到厨房告诉厨师我惛_ƒä»€ä¹ˆï¼ˆå› äØ“(f¨´)我担å¿?j¨©)这样一来我ä¼?x¨¬)吃不下去ï¼?j¨ª)åQŒæˆ‘也不ä¼?x¨¬)亲自到攉™“¶å°ç»™é’±ã€‚这些服务有一个统一的获取方式:(x¨¬)服务员。我æƒ? 吃什么和¾l“èÌŽåQŒå‘Šè¯‰æœåŠ¡å‘˜å›_¯ã€‚关键是˜q™ä¸€æ–¹å¼è¦ç»Ÿä¸€åQŒè¦­‘›_¤Ÿ½Ž€å•。Spring最懒,把服务给你全部注入了(ji¨£n)åQŒå½“然你也可以握住BeanFactoryçš? ¾U¤çº¤¾l†æ‰‹åQŒä¸€ä¸ªä¸€ä¸ªçš„getã€?br />
3、  Â?提供特定于我¾U¿ç¨‹ä¸å®‰å…¨çš„æœåŠ¡
我点äº?ji¨£n)一盘鱼香肉丝,隔壁也点äº?ji¨£n)一盘鱼香肉丝,¾l“果服务员让我们吃同一盘鱼香肉丝。我立刻跌™“v来:(x¨¬)靠,你们的服务不是线½E‹å®‰å…¨çš„吗?åQHibernate çš„Session正是属于˜q™ä¹ˆä¸€¿Uæƒ…况,需要环境进行隔¼›»ï¼Œæˆ‘的唯一职责ž®±æ˜¯åƒé¥­åQæˆ‘的领域逻辑是如何优¾ŸŽçš„˜q›é¤åQäØ“(f¨´)此还要不断重构我吃饭的姿势哩ã€?br /> 好不å®ÒŽ(gu¨©)˜“吃完饭,付完‹Æ¾ï¼Œæ­£å‡†å¤‡ç¦»åœºã€‚服务员风度¾˜©ç¿©åœ°èµ°åˆ°æˆ‘çš„èínæ—ï¼Œæˆ‘ä»¥ä¸ø™¿˜æœ‰æ‰“折券供应åQŒç»“果是åQšæœåŠ¡å‘˜ž®å§è½Õd¯æœ±å”‡åQšå…ˆç”Ÿï¼ŒéºÈƒ¦(ch¨³)æ‚(zh¨¨n)¨æŠŠåƒå‰©çš„盘子清‹z—完毕ã€?br /> 崩溃åQ?br /> 像数据库˜qžæŽ¥çš„æ‰“å¼€åQŒå…³é—­ã€äº‹åŠ¡çš„æ‰“å¼€ã€æäº¤ç­‰éƒ½å±žäºŽè¿è¡ŒæœŸçŽ¯å¢ƒåº”è¯¥åšçš„äº‹æƒ…ã€?br />
4、  Â?其他的七七八å…?br /> 杂事不少åQŒä¾‹å¦‚统一的事件机制、权限拦截等½{‰ã€?br />
二、  �jBPM4的运行期环境
好吧åQŒå…ˆæ¥çœ‹çœ‹å¦‚何徏立jBPM4的运行期环境åQ?br />
EnvironmentFactory environmentFactory = new DefaultEnvironmentFactory();
 
  
 
  Environment environment 
= environmentFactory.openEnvironment();
  
try {
 
     everything available in 
this block 
 
  } 
finally {
    environment.close();
  }


两个关键的类åQšEnvironmentFactoryå’ŒEnvironmentã€?br />
EnvironmentFactory是全局的,在整个应用程序中保持一个实例即可�br />
Environment则是每次æ–ÒŽ(gu¨©)³•调用则要new一个ã€?br />
看看Environment的主要方法:(x¨¬)
public abstract Object get(String name);
public abstract <T> T get(Class<T> type);


是的åQŒenvironment为我们的代码提供所需要的服务¾cÕd®žä¾‹ã€?br />
那么åQŒå¦‚何获得environmentåQ?br /> ¾l§ç®‹çœ‹ï¼š(x¨¬)
public static Environment getCurrent()åQ?/span>

staticåQŒæˆ‘喜欢也。方ä¾Ñ€å¿«æøP¼Œä¸ç®¡æ˜¯åœ¨åœîC¸Šã€èžR上还是房™å¶ä¸ŠåQŒéšå¤„都可调用ã€?br />
那么åQŒäØ“(f¨´)什么Environment每次调用要new呢?
好吧åQŒå½“你需要获取数据库Session的时候,是不是每‹Æ¡éƒ½è¦new呢。Environment提供的服务里包括äº?ji¨£n)非¾U¿ç¨‹å®‰å…¨çš„æ•°æ®åº“操作服务ã€?br />
三、  Â?jBPM4˜qè¡ŒæœŸçŽ¯å¢ƒçš„å®žçŽ°

1、JbpmConfiguration
JbpmConfiguration是jBPM4里最重要的类åQŒå®ƒæ˜¯æ•´ä¸ªåº”用程序的入口。它实现äº?ji¨£n)EnvironmentFactory接口ã€?br />
      JbpmConfiguration加蝲jBPMæ€Èš„配置文äšgåQŒè¿˜æ˜¯å¤§æ¦‚扫一下这个配¾|®æ–‡ä»Óž¼š(x¨¬)
      <jbpm-configuration xmlns="http://jbpm.org/xsd/cfg">

  
<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 />
 
  
</process-engine-context>

  
<transaction-context>
    
<repository-session />
    
<pvm-db-session />
    
<job-db-session />
    
<task-db-session />
    
<message-session />
    
<timer-session />
    
<history-session />
  
</transaction-context>

</jbpm-configuration>


配置文äšg被分ä¸ÞZº†(ji¨£n)两部分,分别是:(x¨¬)process-engine-contextå’Œtransaction-contextã€?br /> 对应于两个IOC容器åQˆWireContextåQ‰çš„配置文äšgã€?br />
ä½œäØ“(f¨´)EnvironmentFactoryåQŒJbpmConfiguration持有成品process-engine-context对应的IOC容器 åQˆå…¨å±€çš„)(j¨ª)实例åQŒæŒæœ‰åŠæˆå“transaction-contextçš„WireDefinition。当调用openEnvironmentæ–ÒŽ(gu¨©)³• æ—Óž¼ŒJbpmConfigurationä¼?x¨¬)new EnvironmentåQŒç„¶åŽå°†process-engine-context IOCå¡«å……å…¥environmentåQŒåŒæ—¶åˆå§‹åŒ–transaction-context IOCåQŒåƈž®†å…¶ä¹Ÿå¡«å……å…¥environment。这样通过environmentž®±å¯ä»¥èŽ·å¾—æ‰€æœ‰æ‰€éœ€è¦çš„æœåŠ¡åQŒåŒ…括全局的和非线½E‹å®‰å…¨çš„æœåŠ¡å®žä¾‹ã€‚ä¹Ÿž®±æ˜¯ environment透过IOC容器提供äº?ji¨£n)查扑֐„¿UæœåŠ¡çš„èƒ½åŠ›ã€?br />

 

2、与¾U¿ç¨‹¾l‘定的environment
environment初始化之å?避免参数传递得一塌糊涂的方式ž®±æ˜¯ž®†environment与线½E‹ç»‘定。看Environment的代码:(x¨¬)
  static ThreadLocal<Environment> currentEnvironment = new ThreadLocal<Environment>();

  
static ThreadLocal<Stack<Environment>> currentEnvironmentStack = new ThreadLocal<Stack<Environment>>();


是的åQŒåœ¨openEnvironmentæ—Óž¼Œæœ‰è¿™ä¹ˆä¸€è¡Œä»£ç ï¼š(x¨¬)
Environment.pushEnvironment(environment);


˜q™æ ·environmentž®×ƒ¸Ž¾U¿ç¨‹¾l‘定äº?ji¨£n),可以通过Environment.getCurrent()ä»ÀL„è°ƒç”¨äº?ji¨£n)ã€?br />
哪里有压˜q«ï¼Œå“ªé‡Œž®±æœ‰æ”¾æŠ—ã€?br /> 在environment.close()æ–ÒŽ(gu¨©)³•里:(x¨¬)

Environment.popEnvironment();


OKåQŒç»“束ã€?br />


]]>
Jbpm4çš„IOC容器http://www.aygfsteel.com/libin2722/articles/286520.html½C¼ç‰©½C¼ç‰©Mon, 13 Jul 2009 02:34:00 GMThttp://www.aygfsteel.com/libin2722/articles/286520.htmlhttp://www.aygfsteel.com/libin2722/comments/286520.htmlhttp://www.aygfsteel.com/libin2722/articles/286520.html#Feedback0http://www.aygfsteel.com/libin2722/comments/commentRss/286520.htmlhttp://www.aygfsteel.com/libin2722/services/trackbacks/286520.html
一、  �Jbpm4 IOC容器介绍
IOC容器的目的是½Ž¡ç†¾l„äšg和实现组件之间的解耦。和Spring里的BeanFactory对应åQŒJbpm4里的接口是ContextåQŒå…·ä½“实现则æ˜? WireContext。Context实际在Jbpm4里有更多的含义,它与Environmentä¸€èµøP¼Œå…±åŒæž„成äº?ji¨£n)代码运行的˜qè¡ŒæœŸçŽ¯å¢ƒã€‚åœ¨˜q™ä¸ªçŽ¯å¢ƒ 里可以获取系¾lŸçš„¾l„äšgåQŒæ›´ä¸ºé‡è¦çš„æ˜¯æä¾›äº†(ji¨£n)数据库连接(sessionåQ‰å’Œäº‹åŠ¡åQˆè¿™ä¸ªç¨åŽä¼š(x¨¬)è®ÔŒ¼‰(j¨ª)ã€?br />
先来看看Context接口的核å¿?j¨©)方法ï¼?x¨¬)
      Object get(String key);
  
<T> T get(Class<T> type);


很明显,提供两种从容器里获取¾l„äšg的方法,一¿Uæ˜¯é€šè¿‡nameåQŒä¸€¿Uæ˜¯é€šè¿‡typeã€?br />
对于IOC容器来说åQŒä¸€èˆ¬æƒ…况下都会(x¨¬)提供一¿UåŠ è½½çš„æ–¹å¼åQŒæ¯”如从xmlæ–‡äšg˜q›è¡ŒåŠ è²ã€ä»Žèµ„æºæ–‡äšg˜q›è¡ŒåŠ è²ã€‚Jbpm4透过WireParser具备从xml加蝲的能力ã€?br />
此外åQŒW(xu¨¦)ireContext通过一个Map¾~“存初始化后的组件ã€?br />
二、  �Jbpm4 IOC容器实现
容器的实现有五个关键¾cÕd’ŒæŽ¥å£åQŒåˆ†åˆ«æ˜¯åQšWireParser、Binding、Descriptor、WireDefinitionå’ŒW(xu¨¦)ireContextã€?br />  

WireParserè¯Õd–xmlæ–‡äšgåQŒåŒæ—¶WireParserä¼?x¨¬)加载一¾pÕdˆ—çš„Binding(默认从jbpm.wire.bindins.xmlæ–‡äšgè¯Õd–加蝲)ã€?br />
Bindingè´Ÿè´£æ ÒŽ(gu¨©)®xml里元素的tagž®†xml元素转换为对应的Descriptorã€?br />
Descriptor负责初始化对象。它们被æ·ÕdŠ åˆ°WireDefinitionã€?br />
WireDefinition被WireParser˜q”回¾l™WireContext。WireContext创徏对象时会(x¨¬)讉K—®WireDefinition里的DescriptoråQŒåŒæ—¶å°†åˆå§‹åŒ–对象的ä»ÕdŠ¡å§”æ‰˜¾l™Descriptor自èínã€?br />
需要注意的是:(x¨¬)Jbpm4在初始化对象时有着四种½{–ç•¥åQŒåˆ†åˆ«æ˜¯åQšåšg˜qŸåˆ›å»ºå’Œåˆå§‹åŒ–、åšg˜qŸåˆ›å»ºå’Œç«‹åˆ»åˆå§‹åŒ–、立åˆÕdˆ›å»ºå’Œå»¶è¿Ÿåˆå§‹åŒ–、立åˆÕdˆ›å»ºå’Œç«‹åˆ»åˆå§‹åŒ–ã€?br />
立刻创徏åQšåœ¨WireContext创徏完毕后对象就已经创徏ã€?br /> 延迟创徏åQšè°ƒç”¨WireContextçš„getæ–ÒŽ(gu¨©)³•èŽ·å–è¯¥å¯¹è±¡æ—¶æ‰åˆ›å»ø™¯¥å¯¹è±¡ã€?br /> 初始化:(x¨¬)一般完成对象属性的注入½{‰æ“ä½œã€?br />
三、  �Jbpm4 IOC容器在Jbpm4里的应用
IOC容器在Jbpm4里最重要的作用就是加载Jbpmçš„æ€Èš„配置文äšgåQˆé»˜è®¤æ˜¯jbpm.cfg.xmlåQ‰ï¼Œ˜q™ä¹Ÿæ˜¯æ•´ä¸ªJbpm应用的è“v炏V€‚大概扫一下这个配¾|®æ–‡ä»Óž¼š(x¨¬)

<?xml version="1.0" encoding="UTF-8"?>

<jbpm-configuration xmlns="http://jbpm.org/xsd/cfg">

  
<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 />
 
  
</process-engine-context>

  
<transaction-context>
    
<repository-session />
    
<pvm-db-session />
    
<job-db-session />
    
<task-db-session />
    
<message-session />
    
<timer-session />
    
<history-session />
  
</transaction-context>

</jbpm-configuration>


可以看到配置文äšg被分ä¸ÞZº†(ji¨£n)两部分,分别是:(x¨¬)process-engine-contextå’Œtransaction-context。在实际应用中,它们 分别对应着两个不同的WireContext:ProcessEngineContextå’ŒTransactionConextã€? ProcessEngineContext覆盖äº?ji¨£n)jbpm4里最重要的服务类åQŒè¿™äº›ç±»æ˜¯å…¨å±€å”¯ä¸€çš„,当然åQŒProcessEngineContext也是 独此一份。本是同根生åQŒå‘½˜qå„不同。TransactionConext则是在每‹Æ¡openEnvironmentæ—‰™‡æ–°åˆ›å»ºï¼Œå› äØ“(f¨´)其包含了(ji¨£n)数据库连接和 事务ã€?br />
贯穿于整个Jbpm4中,˜q™ä¸¤ä¸ªContext被压到Environment里(Environment和线½E‹ç»‘定)(j¨ª)åQŒåœ¨ä»ÖM½•需要的地方都能提供一条龙的服务。于是,在很多领域类里,利用˜q™äº›æœåŠ¡å®žçŽ°å……è¡€æ¨¡åž‹ž®±æ˜¯å¾ˆé¡ºç†æˆç« çš„一件事äº?ji¨£n)ã€?br />
æ€È»“: ProcessEngineContext¾l™å¼•擎领域模型提供全局的组件查找;TransactionConext提供数据库相å…ÏxœåŠ¡ã€?br />


]]>
jBPM4ä»ÕdŠ¡½Ž¡ç†åQšå‚与模式一çž?/title><link>http://www.aygfsteel.com/libin2722/articles/286518.html</link><dc:creator>½C¼ç‰©</dc:creator><author>½C¼ç‰©</author><pubDate>Mon, 13 Jul 2009 02:32:00 GMT</pubDate><guid>http://www.aygfsteel.com/libin2722/articles/286518.html</guid><wfw:comment>http://www.aygfsteel.com/libin2722/comments/286518.html</wfw:comment><comments>http://www.aygfsteel.com/libin2722/articles/286518.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/libin2722/comments/commentRss/286518.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/libin2722/services/trackbacks/286518.html</trackback:ping><description><![CDATA[ <p>原文地址åQ?a >http://www.jboss.org/feeds/post/jbpm_task_management_a_look_at_the_participation_model</a></p> <p>jBPM ä»ÕdŠ¡½Ž¡ç†åQšå‚与模式一çž?br /> Posted on 2009-03-30 09:41:00.0 by Heiko Braun<br /> Since 4.0.0 Beta1<br /> 重新回顾jBPM中的ä»ÕdŠ¡½Ž¡ç†æ¨¡åž‹åQŒå¼•˜q›äº†(ji¨£n)一个新的概念:(x¨¬)ä»ÕdŠ¡å‚ä¸Žã€‚å‚ä¸Žæ¨¡åž‹æ˜qîCº†(ji¨£n)identiesåQˆç”¨æˆähˆ–¾l„)(j¨ª)å’Œä“Q务在实际完成中的参与¾cÕdž‹åQ?br /><img alt="" src="http://www.opug.org.cn/sites/default/files/participation.jpg" /> <br /> ½CÞZ¾‹1åQšç”¨æˆ·å’Œä¸šåŠ¡½Ž¡ç†å‘˜å‚ä¸?br /> 在此与这个模型非帔R€‚合的一个通常的案例是在一个实际执行ä“Q务的用户和一个业务管理员监控˜q›å±•情况之间的区别。依赖于参与¾cÕdž‹åQŒæŸäº›è§„则将实际起作用,而其它的ž®†ç¡®ä¿ä“Q务在¾l™å®šçš„约束内被执行(例如åQŒä¼˜å…ˆçñ”åQŒé¢„定日期等åQ‰ã€?/p> <p>½CÞZ¾‹2åQšå…·æœ‰ä¸åŒçš„参与¾cÕdž‹çš„ä“Q务利益相兌™€?br /> 另一个例子可能是利益相关者监控ä“Q务的实际输出åQŒæˆ–者是在一个ä“Q务上互相协作的不同参与者之间的委托。在˜q™ä¸ªæ¡ˆä¾‹ä¸­ï¼Œä¸€ä¸ªä“Q务的发è“v人,一个候选äh执行˜q™ä¸ªå·¥ä½œòq¶ä¸”最¾lˆçš„与受者可能是不同的参与类型ã€?/p> <p>The TaskService API已经反映äº?ji¨£n)那些变化ï¼?x¨¬)</p> <p> </p> <pre class="java5"> <ol> <li style="font-family: 'Courier New',Courier,monospace; color: black; font-weight: normal; font-style: normal;"> <div style="font-family: 'Courier New',Courier,monospace; font-weight: normal;">org.<span style="color: rgb(0, 102, 0);">jbpm</span>.<span style="color: rgb(0, 102, 0);">TaskService</span><span style="color: rgb(102, 204, 102);">{</span></div> </li> <li style="font-family: 'Courier New',Courier,monospace; color: black; font-weight: normal; font-style: normal;"> <div style="font-family: 'Courier New',Courier,monospace; font-weight: normal;"> </div> </li> <li style="font-family: 'Courier New',Courier,monospace; color: black; font-weight: normal; font-style: normal;"> <div style="font-family: 'Courier New',Courier,monospace; font-weight: normal;"> <span style="color: rgb(102, 204, 102);">[</span>...<span style="color: rgb(102, 204, 102);">]</span></div> </li> <li style="font-family: 'Courier New',Courier,monospace; color: black; font-weight: normal; font-style: normal;"> <div style="font-family: 'Courier New',Courier,monospace; font-weight: normal;"> </div> </li> <li style="font-weight: bold;"> <div style="font-family: 'Courier New',Courier,monospace; font-weight: normal;"> <span style="color: rgb(128, 128, 128); font-style: italic;">/**</span> </div> </li> <li style="font-family: 'Courier New',Courier,monospace; color: black; font-weight: normal; font-style: normal;"> <div style="font-family: 'Courier New',Courier,monospace; font-weight: normal;"> <span style="color: rgb(128, 128, 128); font-style: italic;">  * retrieves a list of tasks for a user</span> </div> </li> <li style="font-family: 'Courier New',Courier,monospace; color: black; font-weight: normal; font-style: normal;"> <div style="font-family: 'Courier New',Courier,monospace; font-weight: normal;"> <span style="color: rgb(128, 128, 128); font-style: italic;">  * and a particular {@link org.jbpm.task.Participation} type</span> </div> </li> <li style="font-family: 'Courier New',Courier,monospace; color: black; font-weight: normal; font-style: normal;"> <div style="font-family: 'Courier New',Courier,monospace; font-weight: normal;"> <span style="color: rgb(128, 128, 128); font-style: italic;">  *</span> </div> </li> <li style="font-family: 'Courier New',Courier,monospace; color: black; font-weight: normal; font-style: normal;"> <div style="font-family: 'Courier New',Courier,monospace; font-weight: normal;"> <span style="color: rgb(128, 128, 128); font-style: italic;">  * @see org.jbpm.TaskQuery</span> </div> </li> <li style="font-weight: bold;"> <div style="font-family: 'Courier New',Courier,monospace; font-weight: normal;"> <span style="color: rgb(128, 128, 128); font-style: italic;">  */</span> </div> </li> <li style="font-family: 'Courier New',Courier,monospace; color: black; font-weight: normal; font-style: normal;"> <div style="font-family: 'Courier New',Courier,monospace; font-weight: normal;"> </div> </li> <li style="font-family: 'Courier New',Courier,monospace; color: black; font-weight: normal; font-style: normal;"> <div style="font-family: 'Courier New',Courier,monospace; font-weight: normal;"> <a > <span style="color: rgb(170, 170, 221); font-weight: bold;">List</span> </a> findTasksByParticipation<span style="color: rgb(102, 204, 102);">(</span><a ><span style="color: rgb(170, 170, 221); font-weight: bold;">String</span></a> participation, UserRef user<span style="color: rgb(102, 204, 102);">)</span>;</div> </li> <li style="font-family: 'Courier New',Courier,monospace; color: black; font-weight: normal; font-style: normal;"> <div style="font-family: 'Courier New',Courier,monospace; font-weight: normal;"> </div> </li> <li style="font-family: 'Courier New',Courier,monospace; color: black; font-weight: normal; font-style: normal;"> <div style="font-family: 'Courier New',Courier,monospace; font-weight: normal;"> <span style="color: rgb(128, 128, 128); font-style: italic;">/**</span> </div> </li> <li style="font-weight: bold;"> <div style="font-family: 'Courier New',Courier,monospace; font-weight: normal;"> <span style="color: rgb(128, 128, 128); font-style: italic;">  * retrieves a list of tasks for a group</span> </div> </li> <li style="font-family: 'Courier New',Courier,monospace; color: black; font-weight: normal; font-style: normal;"> <div style="font-family: 'Courier New',Courier,monospace; font-weight: normal;"> <span style="color: rgb(128, 128, 128); font-style: italic;">  * and a particular {@link org.jbpm.task.Participation} type</span> </div> </li> <li style="font-family: 'Courier New',Courier,monospace; color: black; font-weight: normal; font-style: normal;"> <div style="font-family: 'Courier New',Courier,monospace; font-weight: normal;"> <span style="color: rgb(128, 128, 128); font-style: italic;">  *</span> </div> </li> <li style="font-family: 'Courier New',Courier,monospace; color: black; font-weight: normal; font-style: normal;"> <div style="font-family: 'Courier New',Courier,monospace; font-weight: normal;"> <span style="color: rgb(128, 128, 128); font-style: italic;">  * @see org.jbpm.TaskQuery </span> </div> </li> <li style="font-family: 'Courier New',Courier,monospace; color: black; font-weight: normal; font-style: normal;"> <div style="font-family: 'Courier New',Courier,monospace; font-weight: normal;"> <span style="color: rgb(128, 128, 128); font-style: italic;">  */</span> </div> </li> <li style="font-weight: bold;"> <div style="font-family: 'Courier New',Courier,monospace; font-weight: normal;"> </div> </li> <li style="font-family: 'Courier New',Courier,monospace; color: black; font-weight: normal; font-style: normal;"> <div style="font-family: 'Courier New',Courier,monospace; font-weight: normal;"> <a > <span style="color: rgb(170, 170, 221); font-weight: bold;">List</span> </a> findTasksByParticipation<span style="color: rgb(102, 204, 102);">(</span><a ><span style="color: rgb(170, 170, 221); font-weight: bold;">String</span></a> participation, GroupRef... <span style="color: rgb(0, 102, 0);">groups</span><span style="color: rgb(102, 204, 102);">)</span>;</div> </li> <li style="font-family: 'Courier New',Courier,monospace; color: black; font-weight: normal; font-style: normal;"> <div style="font-family: 'Courier New',Courier,monospace; font-weight: normal;"> </div> </li> <li style="font-family: 'Courier New',Courier,monospace; color: black; font-weight: normal; font-style: normal;"> <div style="font-family: 'Courier New',Courier,monospace; font-weight: normal;"> <span style="color: rgb(102, 204, 102);">}</span> </div> </li> </ol> </pre> <p>目前åQŒæˆ‘们封装了(ji¨£n)一些默认的参与¾cÕdž‹åQŒå…¶ä¸­ä»…仅支持“候选äh”模型,但是你可以期待这些将在不久的ž®†æ¥è¢«æ‰©å±•实现ã€?/p> <p> </p> <p> </p> <pre class="java5"> <ol> <li style="font-family: 'Courier New',Courier,monospace; color: black; font-weight: normal; font-style: normal;"> <div style="font-family: 'Courier New',Courier,monospace; font-weight: normal;">org.<span style="color: rgb(0, 102, 0);">jbpm</span>.<span style="color: rgb(0, 102, 0);">task</span>.<span style="color: rgb(0, 102, 0);">Participation</span><span style="color: rgb(102, 204, 102);">{</span></div> </li> <li style="font-family: 'Courier New',Courier,monospace; color: black; font-weight: normal; font-style: normal;"> <div style="font-family: 'Courier New',Courier,monospace; font-weight: normal;"> <span style="color: rgb(102, 204, 102);">[</span>...<span style="color: rgb(102, 204, 102);">]</span></div> </li> <li style="font-family: 'Courier New',Courier,monospace; color: black; font-weight: normal; font-style: normal;"> <div style="font-family: 'Courier New',Courier,monospace; font-weight: normal;"> <a > <span style="color: rgb(170, 170, 221); font-weight: bold;">String</span> </a> CANDIDATE = <span style="color: rgb(255, 0, 0);">"candidate"</span>;</div> </li> <li style="font-family: 'Courier New',Courier,monospace; color: black; font-weight: normal; font-style: normal;"> <div style="font-family: 'Courier New',Courier,monospace; font-weight: normal;">IdentityRef getIdentityRef<span style="color: rgb(102, 204, 102);">(</span><span style="color: rgb(102, 204, 102);">)</span>;</div> </li> <li style="font-weight: bold;"> <div style="font-family: 'Courier New',Courier,monospace; font-weight: normal;"> <span style="color: rgb(128, 128, 128); font-style: italic;">/** see constants for default participations */</span> </div> </li> <li style="font-family: 'Courier New',Courier,monospace; color: black; font-weight: normal; font-style: normal;"> <div style="font-family: 'Courier New',Courier,monospace; font-weight: normal;"> <a > <span style="color: rgb(170, 170, 221); font-weight: bold;">String</span> </a> getType<span style="color: rgb(102, 204, 102);">(</span><span style="color: rgb(102, 204, 102);">)</span>;</div> </li> <li style="font-family: 'Courier New',Courier,monospace; color: black; font-weight: normal; font-style: normal;"> <div style="font-family: 'Courier New',Courier,monospace; font-weight: normal;"> <span style="color: rgb(102, 204, 102);">}</span> </div> </li> </ol> </pre> <p>敬请期待ã€?/p> <img src ="http://www.aygfsteel.com/libin2722/aggbug/286518.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/libin2722/" target="_blank">½C¼ç‰©</a> 2009-07-13 10:32 <a href="http://www.aygfsteel.com/libin2722/articles/286518.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title> jBPM4½Ž¡ç†æŽ§åˆ¶åîC¸€çž?/title><link>http://www.aygfsteel.com/libin2722/articles/286517.html</link><dc:creator>½C¼ç‰©</dc:creator><author>½C¼ç‰©</author><pubDate>Mon, 13 Jul 2009 02:29:00 GMT</pubDate><guid>http://www.aygfsteel.com/libin2722/articles/286517.html</guid><wfw:comment>http://www.aygfsteel.com/libin2722/comments/286517.html</wfw:comment><comments>http://www.aygfsteel.com/libin2722/articles/286517.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/libin2722/comments/commentRss/286517.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/libin2722/services/trackbacks/286517.html</trackback:ping><description><![CDATA[ <span style="font-size: 10.5pt; font-family: 宋体;">JBoss已经发布äº?ji¨£n)jBPM4 Alpha1版本åQŒè€?008òq?2月,Red Hat发布公告åQŒå·²¾lä¸Žgoogle½{„¡Öväº?ji¨£n)团体共享协议,正式采用GWTä½œäØ“(f¨´)JBoss中间件核å¿?j¨©)组成部分,而jBPM4也作为整个JBoss SOAæ²È†ä½“系的核å¿?j¨©)项目。Heiko Braun在JBoss SOA æ²È†™å¹ç›®çš„博客(<a >http://jboss-overlord.blogspot.com/</a>åQ‰ä¸Š¾l™å‡ºäº?ji¨£n)基于GWTçš„jBPM4的管理控制台一瞥。下面是我的¾˜»è¯‘åQ?/span> <p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: left;" align="left"> <span style="font-size: small;"> <span style="font-family: 宋体;">æ–°çš„</span> <span lang="EN-US"> <span style="font-family: Calibri;">BPM</span> </span> <span style="font-family: 宋体;">控制台已¾lå‘布了(ji¨£n)½W¬ä¸€ä¸ªé‡Œ½E‹ç¢‘åQŒæˆ‘很高兴利用这个机ä¼?x¨¬)介¾lå®ƒæœ€é‡è¦çš„æ”¹å˜åŠ(qi¨¢ng)新特性ã€?/span> </span> <span lang="EN-US"> <img src="http://p.blog.csdn.net/images/p_blog_csdn_net/snow_fox_yaya/EntryImages/20090214/1-definition-list.png" alt="" width="914" height="855" /> </span> </p> <p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: center;" align="center"> <span style="font-family: 宋体;"> <span style="font-size: small;">‹¹ç¨‹å®šä¹‰½Ž¡ç†</span> </span> </p> <p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: left;" align="left"> <span style="font-size: small;"> <span style="font-family: 宋体;">˜qç§»åˆ?/span> <span lang="EN-US"> <span style="font-family: Calibri;">GWT</span> </span> </span> </p> <p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: left;" align="left"> <span style="font-size: small;"> <span style="font-family: 宋体;">­‘Šæ¥­‘Šå¤šçš?/span> <span lang="EN-US"> <span style="font-family: Calibri;">JBoss </span> </span> <span style="font-family: 宋体;">™å¹ç›®æ­£åœ¨˜qç§»åˆ?/span> <span lang="EN-US"> <span style="font-family: Calibri;">GWT</span> </span> <span style="font-family: 宋体;">。他们这么做的原因是åQ?/span> </span> </p> <p class="MsoListParagraph" style="margin: 0cm 0cm 0pt 21pt; text-indent: -21pt; text-align: left;" align="left"> <span style="font-family: Wingdings;" lang="EN-US"> <span style=""> <span style="font-size: small;">Ø</span> <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;">  </span> </span> </span> <span style="font-size: small;"> <span style="font-family: 宋体;">如果你熟æ‚(zh¨¨n)?/span> <span lang="EN-US"> <span style="font-family: Calibri;">Java</span> </span> <span style="font-family: 宋体;">çš„å¼€å‘åÆˆä¸”ä¸æƒÏxˆä¸ÞZ¸‹ä¸€ä»?/span> <span lang="EN-US"> <span style="font-family: Calibri;">web</span> </span> <span style="font-family: 宋体;">开发的专家åQŒé‚£ä¹?/span> <span lang="EN-US"> <span style="font-family: Calibri;">GWT</span> </span> <span style="font-family: 宋体;">是一个比较好的选择。ä‹Éç”?/span> <span lang="EN-US"> <span style="font-family: Calibri;">GWT</span> </span> <span style="font-family: 宋体;">你可以粘ä½?/span> <span lang="EN-US"> <span style="font-family: Calibri;">eclipse</span> </span> <span style="font-family: 宋体;">åQŒå‘åŠ¨ä¸€ä¸ªè°ƒè¯•åÆˆä¸”ç¼–å†™å•å…ƒæµ‹è¯•ï¼›</span> </span> </p> <p class="MsoListParagraph" style="margin: 0cm 0cm 0pt 21pt; text-indent: -21pt; text-align: left;" align="left"> <span style="font-family: Wingdings;" lang="EN-US"> <span style=""> <span style="font-size: small;">Ø</span> <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;">  </span> </span> </span> <span style="font-size: small;"> <span style="font-family: 宋体;">它有一套丰富的</span> <span lang="EN-US"> <span style="font-family: Calibri;">UI</span> </span> <span style="font-family: 宋体;">½H—口部äšgåQŒä½ å¯ä»¥ç«‹é©¬ä½¿ç”¨ã€‚è¿™¿Uçª—口部仉™€šè¿‡è‡ªå·±çš„实çŽîC¿è¯äº†(ji¨£n)一个统一的外观和感觉åQ?/span> </span> </p> <p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: left;" align="left"> <span style="font-size: small;"> <span style="font-family: 宋体;">其它的比较好的成功的</span> <span lang="EN-US"> <span style="font-family: Calibri;">GWT</span> </span> <span style="font-family: 宋体;">实施的例子就æ˜?/span> <span lang="EN-US"> <span style="font-family: Calibri;">Drools </span> </span> <span style="font-family: 宋体;">控制åîCº†(ji¨£n)。(</span> <span lang="EN-US"> <span style="font-family: Calibri;">JBoss</span> </span> <span style="font-family: 宋体;">开源的规则引擎åQ‰ã€?/span> </span> </p> <p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: left;" align="left"> </p> <p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: center;" align="center"> <span style="font-family: 宋体;"> <span style="font-size: small;"> <img src="http://p.blog.csdn.net/images/p_blog_csdn_net/snow_fox_yaya/EntryImages/20090214/2-instance-list.png" alt="" width="914" height="855" /> </span> </span> </p> <p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: center;" align="center"> <span style="font-family: 宋体;"> <span style="font-size: small;">‹¹ç¨‹å®žä¾‹½Ž¡ç†</span> </span> </p> <p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: left;" align="left"> <span style="font-size: small;"> <span lang="EN-US"> <span style="font-family: Calibri;">GWT</span> </span> <span style="font-family: 宋体;">已经非常的流行了(ji¨£n)åQŒå®ƒå…è®¸é€šè¿‡™å¹ç›®æ¥é›†æˆæŽ§åˆ¶å°ã€‚另一斚w¢çš„媄(ji¨£ng)响就是,你可以轻村֜°å¼€å‘一个完整的</span> <span lang="EN-US"> <span style="font-family: Calibri;">GWT</span> </span> <span style="font-family: 宋体;">应用åQŒæˆ–者是一部分åQŒåƈ且同已经存在çš?/span> <span lang="EN-US"> <span style="font-family: Calibri;">web</span> </span> <span style="font-family: 宋体;">应用整合在一赗÷€‚ä‹D例来è¯ß_(d¨¢)¼Œ˜q™æ ·å¯ä»¥å…è®¸ç”¨æˆ·ž®?/span> <span lang="EN-US"> <span style="font-family: Calibri;">BPM</span> </span> <span style="font-family: 宋体;">控制台的ä»ÕdŠ¡½Ž¡ç†åŠŸèƒ½åµŒå…¥åˆîC»–们自å·Þqš„内网应用中ã€?/span> </span> </p> <p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: left;" align="left"> <span style="font-size: small;"> <span style="font-family: 宋体;"> <img src="http://p.blog.csdn.net/images/p_blog_csdn_net/snow_fox_yaya/EntryImages/20090214/3-instance-detail.png" alt="" /> </span> </span> </p> <p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: left;" align="left"> </p> <p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: center;"> <span style="font-size: small;"> <span lang="EN-US"> <span style="font-family: Calibri;">‹¹ç¨‹å®žä¾‹¾l†èŠ‚</span> </span> </span> </p> <p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: center;"> <span style="font-size: small;"> <span lang="EN-US"> </span> </span> </p> <p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: left;" align="left"> <span style="font-size: small;"> <span lang="EN-US"> <span style="font-family: Calibri;">BAM</span> </span> <span style="font-family: 宋体;">åQˆä¸šåŠ¡æ´»åŠ¨ç›‘æŽ§ï¼‰(j¨ª)å?/span> <span lang="EN-US"> <span style="font-family: Calibri;">BI</span> </span> <span style="font-family: 宋体;">åQˆå•†ä¸šæ™ºèƒ½ï¼‰(j¨ª)功能的改˜q?/span> </span> </p> <p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: left;" align="left"> <span style="font-size: small;"> <span style="font-family: 宋体;">或许当前控制台的最大缺点就是缺ž®?/span> <span lang="EN-US"> <span style="font-family: Calibri;">BAM</span> </span> <span style="font-family: 宋体;">å’?/span> <span lang="EN-US"> <span style="font-family: Calibri;">BI</span> </span> <span style="font-family: 宋体;">ç‰ÒŽ(gu¨©)€§ã€?/span> </span> </p> <p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: left;" align="left"> <span style="font-size: small;"> <span style="font-family: 宋体;"> <img src="http://p.blog.csdn.net/images/p_blog_csdn_net/snow_fox_yaya/EntryImages/20090214/5-metric-overview.png" alt="" width="914" height="855" /> </span> </span> </p> <p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: left;" align="left"> </p> <p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: center;" align="center"> <span style="font-family: 宋体;"> </span> </p> <p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: center;" align="center"> <span style="font-family: 宋体;"> <span style="font-size: small;">工作负蝲概览</span> </span> </p> <p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: left;" align="left"> <span style="font-size: small;"> <span style="font-family: 宋体;">改进</span> <span lang="EN-US"> <span style="font-family: Calibri;">BAM</span> </span> <span style="font-family: 宋体;">å’?/span> <span lang="EN-US"> <span style="font-family: Calibri;">BI</span> </span> <span style="font-family: 宋体;">不可能在一天内马上实现åQŒä½†æ˜¯ä½ å¯ä»¥æœŸå¾…在早期的发布版本中看到第一个度量及(qi¨¢ng)状态监控,在我们实çŽîC¸€ä¸ªåŠŸèƒ½é½å…¨çš„</span> <span lang="EN-US"> <span style="font-family: Calibri;">BAM</span> </span> <span style="font-family: 宋体;">控制台的˜q‡ç¨‹ä¸­ï¼Œæˆ‘ä»¬æ­£å°½åŠ›å¢žåŠ æ›´å¤šçš„é›¶æ˜Ÿçš„åŠŸèƒ½ã€‚å› ä¸ø™¿™ž®†ä¸ŽæœåŠ¡‹zÕdŠ¨ç›‘æŽ§™å¹ç›®ä¸­çš„功能和技术发生重叠,感兴­‘£çš„读者可以关注一ä¸?/span> <span lang="EN-US"> <span style="font-family: Calibri;">SAM</span> </span> <span style="font-family: 宋体;">ã€?/span> </span> </p> <p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: left;" align="left"> </p> <p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: center;" align="center"> <span style="font-family: 宋体;"> <span style="font-size: small;"> <img src="http://p.blog.csdn.net/images/p_blog_csdn_net/snow_fox_yaya/EntryImages/20090214/6-metric-detail.png" alt="" width="914" height="855" /> </span> </span> </p> <p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: center;" align="center"> <span style="font-family: 宋体;"> <span style="font-size: small;">性能度量</span> </span> </p> <p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: left;" align="left"> <span style="font-family: 宋体;"> <span style="font-size: small;">如何˜qç§»</span> </span> </p> <p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: left;" align="left"> <span style="font-size: small;"> <span style="font-family: 宋体;">首先åQŒæˆ‘们将åŸÞZºŽ</span> <span lang="EN-US"> <span style="font-family: Calibri;">GWT</span> </span> <span style="font-family: 宋体;">提供一个现å­?/span> <span lang="EN-US"> <span style="font-family: Calibri;">jBPM</span> </span> <span style="font-family: 宋体;">控制台的替代。它?y¨­u)®†ä»ç„¶ä¿æŒå½“前的功能ç‰Ò?gu¨©)€§ï¼Œä½†æ˜¯ä¼?x¨¬)增å?/span> <span lang="EN-US"> <span style="font-family: Calibri;">BI</span> </span> <span style="font-family: 宋体;">功能。最初我们会(x¨¬)òqŒ™¡¡</span> <span lang="EN-US"> <span style="font-family: Calibri;">jBPM3</span> </span> <span style="font-family: 宋体;">的后端功能,然后逐渐地利ç”?/span> <span lang="EN-US"> <span style="font-family: Calibri;">SAM</span> </span> <span style="font-family: 宋体;">的空间来丰富它,甚至最¾lˆå®Œå…¨ä»£æ›¿å®ƒã€?/span> </span> </p> <p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: left;" align="left"> </p> <p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: center;" align="center"> <span style="font-family: 宋体;"> <span style="font-size: small;"> <img src="http://p.blog.csdn.net/images/p_blog_csdn_net/snow_fox_yaya/EntryImages/20090214/4-Enlarge-process.png" alt="" width="914" height="855" /> </span> </span> </p> <p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: center;" align="center"> <span style="font-family: 宋体;"> <span style="font-size: small;">‹¹ç¨‹å›‘ÖŞ视图</span> </span> </p> <p> <span style="font-size: 10.5pt; font-family: 宋体;">¾l§ç®‹å…Ïx³¨ã€‚下‹Æ¡æˆ‘们将要详¾l†è¯´æ˜Žå®žçŽ°ç»†èŠ‚ï¼ŒåŒ…æ‹¬åQ?/span> <span style="font-size: 10.5pt; font-family: "Calibri","sans-serif";" lang="EN-US">gchart</span> <span style="font-size: 10.5pt; font-family: 宋体;">åQ?/span> <span style="font-size: 10.5pt; font-family: "Calibri","sans-serif";" lang="EN-US">gwt</span> <span style="font-size: 10.5pt; font-family: 宋体;">å’?/span> <span style="font-size: 10.5pt; font-family: "Calibri","sans-serif";" lang="EN-US">gwt-ext</span> <span style="font-size: 10.5pt; font-family: 宋体;">ã€?/span> </p> <p> <span style="font-size: 10.5pt; font-family: 宋体;">说明åQšæ­¤æ–‡è‹±æ–‡é“¾æŽ¥ï¼š(x¨¬)<a >http://jboss-overlord.blogspot.com/2008/08/first-glimpse-at-new-bpm-console.html</a></span> </p> <img src ="http://www.aygfsteel.com/libin2722/aggbug/286517.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/libin2722/" target="_blank">½C¼ç‰©</a> 2009-07-13 10:29 <a href="http://www.aygfsteel.com/libin2722/articles/286517.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>jbpm3与jbpm4实现å¯ÒŽ(gu¨©)¯”http://www.aygfsteel.com/libin2722/articles/286513.html½C¼ç‰©½C¼ç‰©Mon, 13 Jul 2009 02:18:00 GMThttp://www.aygfsteel.com/libin2722/articles/286513.htmlhttp://www.aygfsteel.com/libin2722/comments/286513.htmlhttp://www.aygfsteel.com/libin2722/articles/286513.html#Feedback0http://www.aygfsteel.com/libin2722/comments/commentRss/286513.htmlhttp://www.aygfsteel.com/libin2722/services/trackbacks/286513.html

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>



]]>
Ö÷Õ¾Ö©Öë³ØÄ£°å£º ÓÏÑô| »á¶«ÏØ| ³Â°Í¶û»¢Æì| ÅíÉ½ÏØ| ÌØ¿ËË¹ÏØ| Á¬ÖÝÊÐ| ´ó¹ØÏØ| ľÀ¼ÏØ| ʯÆÁÏØ| »´±±ÊÐ| ËÉÅËÏØ| ÄϽ§| ƼÏçÊÐ| ãòÖÝÊÐ| ÖÐÎ÷Çø| ÅíË®| ȪÖÝÊÐ| ¼´Ä«ÊÐ| í¸É½ÏØ| Ðû¶÷ÏØ| зáÏØ| ÖÙ°ÍÏØ| ²ýÄþÏØ| ÃÖÀÕÏØ| í¸É½ÏØ| ð¢É½ÏØ| ÕÅÒ´ÊÐ| ÓåÖÐÇø| ÎͰ²ÏØ| Ì«¿µÏØ| ÓÈÏªÏØ| °¢ÀÕÌ©ÊÐ| ³¤µºÏØ| ÊÖÓÎ| ¸ÊÂåÏØ| ÌÆº£ÏØ| °²Â½ÊÐ| ²©ÀÖÊÐ| ÎÞÎýÊÐ| ¶ëüɽÊÐ| ¹ðƽÊÐ|