Spring und jBPM

Zwar gibt es mit den Spring-Modules bereits Support für die Verwendung von Spring zusammen mit jBPM, aber die Verwendung von Spring-Beans als Actions mit Hilfe des Delegate von Spring-Modules ist etwas umständlich:

<action name="myAction" config-type="bean" 
            class="org.springmodules.workflow.jbpm31.JbpmHandlerProxy">
    <targetBean>jbpmAction</targetBean>
    <factoryKey>jbpmConfiguration</factoryKey>
</action>

Es muss also jedesmal der ProxyHandler hingeschrieben werden und die Target-Bean konfiguriert werden, das sieht doch sehr unschön aus. Meine Vorstellung war eher eine Action-Definition wie diese:

     <spring-action bean="myAction" />

Wie sich zeigt ist jBPM so flexibel, dass diese Vereinfachung mit etwas Konfiguration und einer Hilfsklasse leicht erreicht werden kann.

jBPM Action-Types

jBPM bringt von Haus aus konfigurierbare Action-Types mit. Standardmässig sind dass “action”, “script”, “create-timer” und “cancel-timer”. Diese Action-Types werden in einer XML-Datei konfiguriert. Hier fügen wir zunächst unseren neuen Action-Type “spring-action” ein:

<action-types>
  <action-type element="action"  class="org.jbpm.graph.def.Action" />
  <action-type element="create-timer" class="org.jbpm.scheduler.def.CreateTimerAction" />
  <action-type element="cancel-timer" class="org.jbpm.scheduler.def.CancelTimerAction" />
  <action-type element="script" class="org.jbpm.graph.action.Script" />
  <action-type element="spring-action" class="rinke.solutions.jbpm.SpringActionSupport" />
</action-types>

Damit jBPM diese neue Definition von Action-Types auch verwendet, muss in der Konfiguration von jBPM die Property “resource.action.types” auf die neue Action-Types.xml verweisen:

&lt;jbpm-configuration&gt;
  ....
  &lt;!-- configuration resource files custom for this config --&gt;
  &lt;string name="resource.action.types" value="action.types.xml" /&gt;
  ....
&lt;/jbpm-configuration&gt;

Schließlich wird diese Datei benutzt, um jBPM zu konfigurieren. Hier verwendet man am besten gleich die FactoryBean aus den Spring-Modules, da diese auch die BeanFactory registriert (das wid später gebraucht).

<!-- jBPM configuration -->
<bean id="jbpmConfiguration" 
    class="org.springmodules.workflow.jbpm31.LocalJbpmConfigurationFactoryBean">
	<property name="configuration" value="classpath:jbpm.cfg.xml" />
	....
</bean>

Der Action-Handler

Fehlt noch der Action-Handler für die Spring-Action, der die SpringBean lokalisiert und durch delegiert. Hierzu benutzen wird den FactoryLocator aus den Spring-Modules ganz analog wie der JbpmHandlerProxy:

    package rinke.solutions.jbpm;

    import org.dom4j.Element;
    import org.jbpm.graph.def.Action;
    import org.jbpm.graph.def.ActionHandler;
    import org.jbpm.graph.exe.ExecutionContext;
    import org.jbpm.jpdl.xml.JpdlXmlReader;
    import org.jbpm.jpdl.xml.Parsable;
    import org.springframework.beans.factory.access.BeanFactoryReference;
    import org.springmodules.workflow.jbpm31.JbpmFactoryLocator;

    /**
    * Delegates a spring-action to the referenced spring bean
    */
    public class SpringActionSupport extends Action implements Parsable {

      private static final long serialVersionUID = 1L;
      /**
       * stores the name of the spring bean to delegate to.
       */
      private String beanname;

      /**
       * executes the action. 1st the default BeanFactory is located (with JbpmFactoryLocator).
       * 2nd the bean is located and delegated to.
       */
      public void execute(ExecutionContext executionContext) throws Exception {
        JbpmFactoryLocator locator = new JbpmFactoryLocator();
        BeanFactoryReference reference = locator.useBeanFactory(null);
        ActionHandler springAction = (ActionHandler) reference.getFactory().getBean(beanname, ActionHandler.class);
        springAction.execute(executionContext);
        reference.release();
      }

      /**
       * read bean name from attribute
       */
      public void read(Element element, JpdlXmlReader jpdlReader) {
        beanname = element.attributeValue("bean");
      }

      /**
       * not used
       */
      public void write(Element element) {
      }

    } 
Dieser Beitrag wurde unter Java veröffentlicht. Setze ein Lesezeichen auf den Permalink.

Eine Antwort auf Spring und jBPM

Hinterlasse eine Antwort

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind markiert *