activiti監聽器的使用總結

監聽器listener

監聽器分爲三種:JavaDelegate TaskListener ExecutionListener

用戶任務(UserTask)的監聽器爲TaskListener

Java服務任務(JavaServiceTask)的監聽器爲JavaDelegate

其他的服務的監聽器爲ExecutionListener

TaskListener中參數(DelegateTask)是有關於userTask的

JavaDelegate和ExecutionListener參數(DelegateExecution)是有關於流程的

使用監聽器的方式有三種:

1.直接是用class的方式,如下標籤

activiti:class="org.activiti.examples.bpmn.servicetask.ToUpperCaseFieldInjected"

2.用expression的方式(這種方式還沒有試驗過,之後補充)

<activiti:expression>${genderBean.getGenderString(gender)}</activiti:expression>

3.用delegateExpression的方式

activiti:delegateExpression="${someJavaDelegateBean}"

這種方式是利用bean進行查找類的,someJavaDelegateBean是bean,比如現在項目都是由spring管理的,可以在監聽器的類上直接加上@Service("someJavaDelegateBean")

利用這種方式可以和spring進行無縫對接,也解決自定義的service無法注入的問題。第一種方式是服務自定注入自定義service的;@Autowired

filedName的用法

三中方式

<activiti:field name="text" stringValue="Hello World" />

public class ToUpperCaseFieldInjected implements JavaDelegate {
    private Expression text;
    public void execute(DelegateExecution execution) {
        execution.setVariable("var", ((String)text.getValue(execution)).toUpperCase());
    }
}

普通字符文本

<extensionElements>
    <activiti:field name="text">
	<activiti:string>
		This is a long string with a lot of words and potentially way longer even!
	</activiti:string>
     </activiti:field>
</extensionElements>

較長文本,比如郵件;

<serviceTask id="javaService" name="Java service invocation"
activiti:class="org.activiti.examples.bpmn.servicetask.ReverseStringsFieldInjected">
    <extensionElements>
        <activiti:field name="text1">
        	<activiti:expression>${genderBean.getGenderString(gender)}</activiti:expression>
        </activiti:field>
        <activiti:field name="text2">
        	<activiti:expression>Hello ${gender == 'male' ? 'Mr.' : 'Mrs.'} ${name}</activiti:expression>
        </activiti:field>
    </ extensionElements>
</ serviceTask>
public class ReverseStringsFieldInjected implements JavaDelegate {
    private Expression text1;
    private Expression text2;
    public void execute(DelegateExecution execution) {
        String value1 = (String) text1.getValue(execution);
        execution.setVariable("var1", new StringBuffer(value1).reverse().toString());
        String value2 = (String) text2.getValue(execution);
        execution.setVariable("var2", new StringBuffer(value2).reverse().toString());
    }
}

運行時動態注入的值,可以使用表達式,這種表達式可以使用流程變量,或是spring中定義的bean

上面爲bpmn標籤

如果監聽器使用class的方式,那麼需要在監聽器中添加 private Expression text; // 名字需要和filedName一致 如果不加,則會拋出異常;

public class ToUpperCaseFieldInjected implements JavaDelegate {
    private Expression text;
    public void execute(DelegateExecution execution) {
        execution.setVariable("var", ((String)text.getValue(execution)).toUpperCase());
    }
}

但是上面提到class的方式不能@autowired 會爲null

activiti:delegateExpression這種方式可以@autowired,但是這種方式不能保證線程安全,那怎麼改動呢?

首先我們需要知道:

delegateExpressionFieldInjectionMode參數(取org.activiti.engine.imp.cfg.DelegateExpressionFieldInjectionMode枚舉中的值)

這個參數的可以進行設置;(包含以下三種)

DISABLED(禁用):當使用代理表達式時,完全禁用字段注入。不會再嘗試進行字段注入。這是最安全的方式,保證線程安全。
COMPATIBILITY(兼容):在這個模式下,行爲與5.21版本之前完全一樣:可以在代理表達式中使用字段注入,如果代理類中沒有定義該字段,會拋出異常。這是最不線程安全的模式,但可以保證歷史版本兼容性,也可以在代理表達式只在一個任務中使用的時候(因此不會產生併發競爭條件),安全使用。
MIXED(混合):可以在使用代理表達式時注入,但當代理中沒有定義字段時,不會拋出異常。這樣可以在部分代理中使用注入(例如不是單例時),而在部分代理中不使用注入。

Activiti 5.x版本的默認模式爲COMPATIBILITY(兼容)。
Activiti 6.x版本的默認模式爲MIXED(混合)。

@Service("myJavaDelegate")
public class MyJavaDelegate implements JavaDelegate {
//    Expression expression;

    @Override
    public void execute(DelegateExecution execution) {
        Expression operationsLocal = DelegateHelper.getFieldExpression(execution, "operationsLocal");
        execution.setVariable("operationsLocal",operationsLocal.getExpressionText());
    }
}

以上只是單例模式,如果是多例(scope=“prototype”)不需要這種方式

其中JavaServiceTask 中有一個activiti:resultVariable的標籤

服務執行的返回值(僅對使用表達式的服務任務),可以通過爲腳本任務定義的’activiti:resultVariable’屬性設置流程變量名,指定爲已經存在的,或者新的流程變量。指定的已有值的流程變量,會被服務執行的結果值覆蓋。當不指定結果變量名時,服務執行的結果值將被忽略。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章