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:

<jbpm-configuration>
  ....
  <!-- configuration resource files custom for this config -->
  <string name="resource.action.types" value="action.types.xml" />
  ....
</jbpm-configuration>

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

}

Kommentare

Ansicht der Kommentare: (Linear | Verschachtelt)

  1. Joachim Mönch schreibt:

    Klasse! Das macht die ganze Sache in der Tat ein gutes Stück händelbarer. Wirklich schöne Idee!


Kommentar schreiben


Umschließende Sterne heben ein Wort hervor (*wort*), per _wort_ kann ein Wort unterstrichen werden.
Standard-Text Smilies wie :-) und ;-) werden zu Bildern konvertiert.

Um maschinelle und automatische Übertragung von Spamkommentaren zu verhindern, bitte die Zeichenfolge im dargestellten Bild in der Eingabemaske eintragen. Nur wenn die Zeichenfolge richtig eingegeben wurde, kann der Kommentar angenommen werden. Bitte beachten Sie, dass Ihr Browser Cookies unterstützen muss um dieses Verfahren anzuwenden.
CAPTCHA