(4)activiti工作流引擎之uel表達式


有了前面幾章,我們肯定有一定的困惑,activiti如何與實際業務整合,比如一條采購單,如何跟一個流程實例互相關聯起來?

這里就需要使用到activiti啟動流程實例時設置一個流程實例的businessKey(一般存儲我們一條采購單的id)

1,啟動流程實例設置其businessKey

/**
     * 啟動一個流程實例,設置其業務id
     */
    @Test
    public void startProInsWithKey() {
        RuntimeService runtimeService = engine.getRuntimeService();

        String processDefinitionKey = "purchasingflow";
        //設置一個businessKey,在我實際業務中可能是一個采購單,或者訂單之類的id
        String businessKey ="111";
        // 根據流程定義的key啟動一個流程實例
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(processDefinitionKey,businessKey);
        System.out.println("流程實例id:" + processInstance.getId());
        System.out.println("流程定義id:" + processInstance.getProcessDefinitionId());

    }

 一般情況下,我們是在用戶保存一條采購單的時候,啟動這個實例,並且動態獲取采購單的id(也就是用作流程實例的businessKey),並且我們還會在采購單表中保存這個流程實例的id,雙向一對一綁定,方便業務查詢

2,根據采購單的id(也就是用作流程實例的businessKey),動態的查詢出對應的流程實例

/**
     * 通過businessKey查詢流程實例
     */
    @Test
    public void queryProInsWithKey(){
        RuntimeService runtimeService = engine.getRuntimeService();
        String businessKey ="111";
        
        ProcessInstanceQuery instanceQuery = runtimeService.createProcessInstanceQuery();
        //根據其流程定義key和業務id businessKey查詢出對應的流程實例,一般只有一條
        instanceQuery.processInstanceBusinessKey(businessKey);
        //查詢出唯一的一條流程實例
        ProcessInstance processInstance = instanceQuery.singleResult();
        
        System.out.println("流程實例id:"+processInstance.getId());
        System.out.println("流程定義id:"+processInstance.getProcessDefinitionId());
        
    }

到這里,我們就清楚了一個流程實例和實際業務數據的綁定

 

大家到這里也啟動了很多的流程實例了,發現我們的任務辦理人都是寫死為zhangsan,lisi之類的,那么我們可以動態的指定嗎,這就需要使用到我們的uel表達式了

首先uel表達式到底是什么呢?

UEL是java EE6規范的一部分,UEL(Unified Expression Language)即統一表達式語言,activiti支持兩個UEL表達式:UEL-valueUEL-method。我們都會分別做介紹

(一)我們先來演示uel-value

首先做個簡單的使用帶大家入門

使用步驟:(看不明白的運行下面的代碼走一遍再回頭看)

1,在任務的節點,不直接指定處理人的id,設置處理人表達式${assignee},並且重新部署流程定義

2, 啟動一個流程實例是設置啟動變量動態設置assignee的值

3,查看並驗證下一個任務的處理人是否為我們動態設置

 

1,首先我們設置節點

2,在啟動代碼時動態設置assignee的值

/**
     * 啟動流程實例時設置全局變量
     */
    @Test
    public void startProInsWithArgs(){
        
        RuntimeService runtimeService = engine.getRuntimeService();

        String processDefinitionKey = "purchasingflow";
        //設置其啟動的全局變量參數,其value可以是javabean,也可以是普通字符串,數字
        Map<String,Object> variables = new HashMap<String, Object>();
        variables.put("assignee", "feige");
        //設置流程啟動時,設置參數啟動
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(processDefinitionKey,variables);
        System.out.println("流程實例id:" + processInstance.getId());
        System.out.println("流程定義id:" + processInstance.getProcessDefinitionId());
        
    }

3,這個時候我們通過查看數據庫,查看act_ru_task當前運行的任務,查看

從上面的我們可以看到流程走到了,創建采購單,並且采購的assignee處理人為feige

因為當我們走到了創建采購單時,會從當前流程實例的全局變量查找name為assignee的值,如果查詢到,則將這個assignee的值賦給這個節點,如果我們動態設置了,但是走到這個節點前(為什么說節點前呢,因為還可以在別的時候設置變量,后面的章節會講)

沒有找到這個assignee變量的值,會報錯的,大家可以自己試一試

 


 

當然除了上面的設置方法,我們還有其他的設置方法來動態設置其節點的值嗎?答案是肯定的,啟動的流程時候的參數的value,不僅僅可以是String類型,還可以是Object對象(序列化的),Map,List,Array

我們這里采用對象做演示,執行步驟如下

1,設置流程的第一個節點動態的值為${user.userId},他會默認查找變量name為user的對應的值的getUserId獲取值,重新部署流程定義

2,啟動流程時,設置這個user的javabean到流程的全局變量中

3,查看走到這個節點的當前任務的處理人是否是我們user的userId變量的值

 

1,設置節點

 

2,設置javabean  User對象並且在流程實例啟動時設置進去

public class User implements Serializable{
    /**
     * 用於序列化
     */
    private static final long serialVersionUID = 7717000074223077256L;
    private String userId;
    private String sex;
    private String name;
    
    public User(String userId, String sex, String name) {
        super();
        this.userId = userId;
        this.sex = sex;
        this.name = name;
    }
    public String getUserId() {
        return userId;
    }
    public void setUserId(String userId) {
        this.userId = userId;
    }
    public String getSex() {
        return sex;
    }
    public void setSex(String sex) {
        this.sex = sex;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }

}
/**
     * 啟動流程設置一個user用戶到全局變量中
     */
    @Test
    public void startProInsWithObj(){
        
        RuntimeService runtimeService = engine.getRuntimeService();

        String processDefinitionKey = "purchasingflow";
        
        //設置其啟動的全局變量參數,其value設置為user對象,這里寫死
        User user = new User("101","男","張三");
        
        Map<String,Object> variables = new HashMap<String, Object>();
        variables.put("user", user);
        //設置流程啟動時,設置參數啟動
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(processDefinitionKey,variables);
        System.out.println("流程實例id:" + processInstance.getId());
        System.out.println("流程定義id:" + processInstance.getProcessDefinitionId());
        
    }

3,到這里流程實例啟動成功,我們觀察數據庫的當前任務表,觀察第一個節點的處理人是否為我們設置的101的userId

 

 設置成功!

 

(二)演示uel-method

執行步驟

1,設置節點的執行人為${method.getUserNameByUserId(userId)} ,其中method方法是我們注入到spring中的一個類,userId是我們設置的全局變量

2,將method方法注入到activiti的processEngineConfiguration的bean中(在我們的activiti.cfg.xml中)

3,啟動一個流程設置全局變量userId作為啟動參數,看看是否走到這個節點的處理人是我們method方法getUserNameByUserId返回的name

 

好了,直接上代碼

1,設置節點,重新部署流程定義

 

2,method的java方法和activiti.cfg.xml的注入配置

public class CommonMethod{

    public String getUserNameByUserId(int userId){
        
        return "activiti"+userId;
        
    }

}
<bean class="cn.nfcm.po.CommonMethod" id="commonmethod"></bean>
    
    <bean id="processEngineConfiguration"
        class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration">
        <!-- 數據源 -->
        <property name="dataSource" ref="dataSource" />
        <!-- activiti數據庫表處理策略 -->
        <property name="databaseSchemaUpdate" value="true" />
        <!-- 可以注入多個類到activiti的beans中,其中key對應的就是我們的類名 -->
        <property name="beans">
            <map>
                <entry key="commonmethod" value-ref="commonmethod" />
            </map>
        </property>
    </bean>

3,啟動一個流程實例

/**
     * 根據方法得到值
     */
    @Test
    public void startProInsWithMethod(){

        RuntimeService runtimeService = engine.getRuntimeService();

        String processDefinitionKey = "purchasingflow";
        //這里設置userId為8,走到第一個節點會查找我們注入進去的commonmethod的getUserNameByUserId方法並傳遞userId
        Map<String,Object> variables = new HashMap<String, Object>();
        variables.put("userId", 8);
        
        //設置流程啟動時,設置參數啟動
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(processDefinitionKey,variables);
        System.out.println("流程實例id:" + processInstance.getId());
        System.out.println("流程定義id:" + processInstance.getProcessDefinitionId());
        
        
    }

到這里我們會發現流程啟動成功,並且流程的當前任務處理人為acitiviti8,在實際的應用中因為都是spring管理的類,我們可以進行多種多樣的查詢賦值,非常方便!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM