Osworkflow整合Spring

一、先看一下spring配置文件中的配置内容:

1、首先设置数据源dataSource:

<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
  <property name="locations">
    <list>
      <value>classpath:conf/jdbc.properties</value>
    </list>
  </property>
</bean>

  

 1 <bean id="dataSource" destroy-method="close" class="org.apache.commons.dbcp.BasicDataSource">
 2         <property name="driverClassName">
 3             <value>${driverClassName}</value>
 4         </property>
 5         <property name="url">
 6             <value>${urlAddr}</value>
 7         </property>
 8         <property name="username">
 9             <value>${username}</value>
10         </property>
11         <property name="password">
12             <value>${password}</value>
13         </property>
14         <property name="maxActive">
15             <value>${maxActive}</value>
16         </property>
17         <property name="maxIdle">
18             <value>${maxIdle}</value>
19         </property>
20         <property name="minIdle">
21             <value>${minIdle}</value>
22         </property>
23         <property name="maxWait">
24             <value>${maxWait}</value>
25         </property>
26         <property name="timeBetweenEvictionRunsMillis">
27             <value>${timeBetweenEvictionRunsMillis}</value>
28         </property>
29         <property name="minEvictableIdleTimeMillis">
30             <value>${minEvictableIdleTimeMillis}</value>
31         </property>
32         <property name="testWhileIdle">
33             <value>${mysqlTestWhileIdle}</value>
34         </property>
35         <property name="testOnReturn" value="true" />
36         <property name="testOnBorrow" value="true"/> 
37         <property name="validationQuery">
38             <value>${mysqlValidationQuery}</value>
39         </property>
40         <property name="removeAbandoned">
41             <value>true</value>
42         </property> 
43         <property name="removeAbandonedTimeout">
44             <value>180</value>
45         </property> 
46     </bean>

2、设置Osworkflow:

<bean id="workflowStore" class="com.opensymphony.workflow.spi.jdbc.ExtMySQLWorkflowStore" init-method="init">
        <property name="dataSource" ref="dataSource"></property>
        <property name="map">
            <map>
                <entry key="step.sequence.increment" value="INSERT INTO OS_STEPIDS (ID) values (null)">
                </entry>
                <entry key="step.sequence.retrieve" value="SELECT max(ID) FROM OS_STEPIDS">
                </entry>
                <entry key="entry.sequence.increment" value="INSERT INTO os_entryids (ID) values (null)">
                </entry>
                <entry key="entry.sequence.retrieve" value="SELECT max(ID) FROM os_entryids">
                </entry>
                <entry key="entry.sequence" value="SELECT max(id)+1 FROM OS_WFENTRY"/>
                <entry key="entry.table" value="OS_WFENTRY"/>
                <entry key="entry.id" value="ID"/>
                <entry key="entry.name" value="NAME"/>
                <entry key="entry.state" value="STATE"/>
                <entry key="step.sequence"
                    value="SELECT max(ID)+1 FROM OS_STEPIDS"/>
                <entry key="step.sequence.increment"
                    value="INSERT INTO OS_STEPIDS (ID) values (null)"/>
                <entry key="step.sequence.retrieve"
                    value="SELECT max(ID) FROM OS_STEPIDS"/>
                <entry key="history.table" value="OS_HISTORYSTEP"/>
                <entry key="current.table" value="OS_CURRENTSTEP"/>
                <entry key="historyPrev.table" value="OS_HISTORYSTEP_prev"/>
                <entry key="currentPrev.table" value="OS_CURRENTSTEP_prev"/>
                <entry key="step.id" value="ID"/>
                <entry key="step.entryId" value="ENTRY_ID"/>
                <entry key="step.stepId" value="STEP_ID"/>
                <entry key="step.actionId" value="ACTION_ID"/>
                <entry key="step.owner" value="OWNER"/>
                <entry key="step.caller" value="CALLER"/>
                <entry key="step.startDate" value="START_DATE"/>
                <entry key="step.finishDate" value="FINISH_DATE"/>
                <entry key="step.dueDate" value="DUE_DATE"/>
                <entry key="step.status" value="STATUS"/>
                <entry key="step.divviousId" value="divVIOUS_ID"/>
            </map>
        </property>
    </bean>
    <bean id="workflowFactory" class="com.opensymphony.workflow.loader.XMLWorkflowFactory" init-method="initDone"/>
    <bean id="workflowConfiguration" class="com.opensymphony.workflow.config.SpringConfiguration">
        <property name="store" ref="workflowStore"/>
        <property name="factory" ref="workflowFactory"/>
    </bean>
    <bean id="workflowTypeResolver" class="com.opensymphony.workflow.util.SpringTypeResolver"/>
    <bean id="workflow" class="com.jd.bse.osworkflow.ExtBasicWorkflow" scope="prototype">
        <constructor-arg value="bjjdz"/>
        <property name="configuration" ref="workflowConfiguration"/>
        <property name="resolver" ref="workflowTypeResolver"/>
    </bean>

3、事务管理器:

<bean id="txManager"
        class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>
<tx:annotation-driven transaction-manager="txManager"/>
<bean id="sharedTransactionTemplate"
        class="org.springframework.transaction.support.TransactionTemplate">
        <constructor-arg ref="txManager"></constructor-arg>
        <property name="isolationLevelName" value="ISOLATION_READ_UNCOMMITTED"/>
        <property name="timeout" value="30"/>
    </bean>

4、首先看类ExtMySQLWorkflowStore,与最顶层接口继承关系是ExtMySQLWorkflowStore->MySQLWorkflowStore->JDBCWorkflowStore->WorkflowStore,除了自定义扩展的ExtMySQLWorkflowStore。其它都是osworkflow自带类或者接口,首先看ExtMySQLWorkflowStore类:

public class ExtMySQLWorkflowStore extends MySQLWorkflowStore {
    //防止并发
    private ThreadLocal<Connection> threadlocal = new ThreadLocal<Connection>();//当使用ThreadLocal维护变量时,ThreadLocal为每个使用该变量的线程提供独立的变量副本,所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本
    private Map<String,String> map;//对应上面spring配置文件中workflowStore中的map,传递参数
     private DataSource dataSource;//对应spring配置文件中的dataSource,设置数据源
    public void init() throws StoreException {
        if(null!=map){
            map.put("datasource",null);
        }
        super.init(map);
        super.ds=dataSource;

    }

    public Connection getConnection() throws SQLException{
        Connection con = threadlocal.get();
        if((null != con) && !con.isClosed()){
            System.out.println("getConnection"+con.hashCode());
            return con ;
        }else{
            con = super.ds.getConnection();
            System.out.println("|-------------"+Thread.currentThread().getId());
            setConnection(con);
            System.out.println("super.ds.getConnection"+con.hashCode());
            return  con;
        }

    }

    public void setConnection(Connection connection) {
        threadlocal.set(connection);
//        this.connection = connection;
    }

    public Map<String, String> getMap() {
        return map;
    }

    public void setMap(Map<String, String> map) {
        this.map = map;
    }

    public DataSource getDataSource() {
        return dataSource;
    }

    public void setDataSource(DataSource dataSource) {
        this.dataSource = dataSource;
    }
     @Override
    public PropertySet getPropertySet(long entryId) {
        HashMap args = new HashMap(1);
        args.put("globalKey", "osff_" + entryId);
         PropertySet ps=  PropertySetManager.getInstance("memory", args);
         ps.setString("col.globalKey","GLOBAL_KEY");
         ps.setString("col.itemKey","ITEM_KEY");
         ps.setString("col.itemType","ITEM_TYPE");
         ps.setString("col.string","STRING_VALUE");
         ps.setString("col.date","DATE_VALUE");
         ps.setString("col.data","DATA_VALUE");
         ps.setString("col.float","FLOAT_VALUE");
         ps.setString("col.number","NUMBER_VALUE");

         return ps;
    }
}

5、再看MySQLWorkflowStore:

public class MySQLWorkflowStore extends JDBCWorkflowStore {
    //~ Instance fields ////////////////////////////////////////////////////////

    private String _stepSequenceIncrement = null;
    private String _stepSequenceRetrieve = null;

    //~ Methods ////////////////////////////////////////////////////////////////

    public void init(Map props) throws StoreException {
        super.init(props);
        _stepSequenceIncrement = (String) props.get("step.sequence.increment");
        _stepSequenceRetrieve = (String) props.get("step.sequence.retrieve");
    }

    protected long getNextStepSequence(Connection c) throws SQLException {
        PreparedStatement stmt = null;
        ResultSet rset = null;

        try {
            stmt = c.prepareStatement(_stepSequenceIncrement);
            stmt.executeUpdate();
            rset = stmt.executeQuery(_stepSequenceRetrieve);

            rset.next();

            long id = rset.getLong(1);

            return id;
        } finally {
            cleanup(null, stmt, rset);
        }
    }
}

6、再看JDBCWorkflowStore,因为代码比较长,所以一个片段一个片段讲:

public class JDBCWorkflowStore implements WorkflowStore

首先定义一些属性:

protected DataSource ds;
    protected String currentPrevTable;
    protected String currentTable;
    protected String entryId;
    protected String entryName;
    protected String entrySequence;
    protected String entryState;
    protected String entryTable;
    protected String historyPrevTable;
    protected String historyTable;
    protected String stepActionId;
    protected String stepCaller;
    protected String stepDueDate;
    protected String stepEntryId;
    protected String stepFinishDate;
    protected String stepId;
    protected String stepOwner;
    protected String stepPreviousId;
    protected String stepSequence;
    protected String stepStartDate;
    protected String stepStatus;
    protected String stepStepId;
    protected boolean closeConnWhenDone = false;

然后在init方法中初始化这些变量:

public void init(Map props) throws StoreException {
        entrySequence = getInitProperty(props, "entry.sequence", "SELECT nextVal('seq_os_wfentry')");
        stepSequence = getInitProperty(props, "step.sequence", "SELECT nextVal('seq_os_currentsteps')");
        entryTable = getInitProperty(props, "entry.table", "OS_WFENTRY");
        entryId = getInitProperty(props, "entry.id", "ID");
        entryName = getInitProperty(props, "entry.name", "NAME");
        entryState = getInitProperty(props, "entry.state", "STATE");
        historyTable = getInitProperty(props, "history.table", "OS_HISTORYSTEP");
        currentTable = getInitProperty(props, "current.table", "OS_CURRENTSTEP");
        currentPrevTable = getInitProperty(props, "currentPrev.table", "OS_CURRENTSTEP_PREV");
        historyPrevTable = getInitProperty(props, "historyPrev.table", "OS_HISTORYSTEP_PREV");
        stepId = getInitProperty(props, "step.id", "ID");
        stepEntryId = getInitProperty(props, "step.entryId", "ENTRY_ID");
        stepStepId = getInitProperty(props, "step.stepId", "STEP_ID");
        stepActionId = getInitProperty(props, "step.actionId", "ACTION_ID");
        stepOwner = getInitProperty(props, "step.owner", "OWNER");
        stepCaller = getInitProperty(props, "step.caller", "CALLER");
        stepStartDate = getInitProperty(props, "step.startDate", "START_DATE");
        stepFinishDate = getInitProperty(props, "step.finishDate", "FINISH_DATE");
        stepDueDate = getInitProperty(props, "step.dueDate", "DUE_DATE");
        stepStatus = getInitProperty(props, "step.status", "STATUS");
        stepPreviousId = getInitProperty(props, "step.previousId", "PREVIOUS_ID");

        String jndi = (String) props.get("datasource");

        if (jndi != null) {
            try {
                ds = (DataSource) lookup(jndi);

                if (ds == null) {
                    ds = (DataSource) new javax.naming.InitialContext().lookup(jndi);
                }
            } catch (Exception e) {
                throw new StoreException("Error looking up DataSource at " + jndi, e);
            }
        }
    }

其它主要还有一些方法就是对osworkflow表的操作。

原文地址:https://www.cnblogs.com/zhli/p/4917638.html