{"id":35,"date":"2007-10-11T20:53:21","date_gmt":"2007-10-11T20:53:21","guid":{"rendered":"http:\/\/euve3303.vserver.de\/stefan\/blog\/?p=38"},"modified":"2011-12-02T21:07:44","modified_gmt":"2011-12-02T20:07:44","slug":"spring-und-jbpm","status":"publish","type":"post","link":"https:\/\/cogito-ergo-blog.de\/blog\/2007\/10\/11\/spring-und-jbpm\/","title":{"rendered":"Spring und jBPM"},"content":{"rendered":"<p>Zwar gibt es mit den <a href=\"https:\/\/springmodules.dev.java.net\/ \">Spring-Modules<\/a> bereits Support f\u00fcr die Verwendung von Spring zusammen mit <a href=\"http:\/\/www.jboss.com\/products\/jbpm\">jBPM<\/a>, aber die Verwendung von Spring-Beans als Actions mit Hilfe des Delegate von Spring-Modules ist etwas umst\u00e4ndlich:<\/p>\n<pre class=\"brush: xml; title: ; notranslate\" title=\"\">\r\n&lt;action name=&quot;myAction&quot; config-type=&quot;bean&quot; \r\n            class=&quot;org.springmodules.workflow.jbpm31.JbpmHandlerProxy&quot;&gt;\r\n    &lt;targetBean&gt;jbpmAction&lt;\/targetBean&gt;\r\n    &lt;factoryKey&gt;jbpmConfiguration&lt;\/factoryKey&gt;\r\n&lt;\/action&gt;\r\n<\/pre>\n<\/p>\n<p>Es muss also jedesmal der ProxyHandler hingeschrieben werden und die Target-Bean konfiguriert werden, das sieht doch sehr unsch\u00f6n aus. Meine Vorstellung war eher eine Action-Definition wie diese:<\/p>\n<pre class=\"brush: xml; title: ; notranslate\" title=\"\">\r\n     &lt;spring-action bean=&quot;myAction&quot; \/&gt;\r\n<\/pre>\n<\/p>\n<p>Wie sich zeigt ist jBPM so flexibel, dass diese Vereinfachung mit etwas Konfiguration und einer Hilfsklasse leicht erreicht werden kann.<\/p>\n<p><!--more--><\/p>\n<h3>jBPM Action-Types<\/h3>\n<p>jBPM bringt von Haus aus konfigurierbare Action-Types mit. Standardm\u00e4ssig sind dass &#8220;action&#8221;, &#8220;script&#8221;, &#8220;create-timer&#8221; und &#8220;cancel-timer&#8221;. Diese Action-Types werden in einer XML-Datei konfiguriert. Hier f\u00fcgen wir zun\u00e4chst unseren neuen Action-Type &#8220;spring-action&#8221; ein:<\/p>\n<pre class=\"brush: xml; title: ; notranslate\" title=\"\">\r\n&lt;action-types&gt;\r\n  &lt;action-type element=&quot;action&quot;  class=&quot;org.jbpm.graph.def.Action&quot; \/&gt;\r\n  &lt;action-type element=&quot;create-timer&quot; class=&quot;org.jbpm.scheduler.def.CreateTimerAction&quot; \/&gt;\r\n  &lt;action-type element=&quot;cancel-timer&quot; class=&quot;org.jbpm.scheduler.def.CancelTimerAction&quot; \/&gt;\r\n  &lt;action-type element=&quot;script&quot; class=&quot;org.jbpm.graph.action.Script&quot; \/&gt;\r\n  &lt;action-type element=&quot;spring-action&quot; class=&quot;rinke.solutions.jbpm.SpringActionSupport&quot; \/&gt;\r\n&lt;\/action-types&gt;\r\n<\/pre>\n<\/p>\n<p>Damit jBPM diese neue Definition von Action-Types auch verwendet, muss in der Konfiguration von jBPM die Property &#8220;resource.action.types&#8221; auf die neue Action-Types.xml verweisen:<\/p>\n<pre class=\"brush: xml; title: ; notranslate\" title=\"\">\r\n&amp;lt;jbpm-configuration&amp;gt;\r\n  ....\r\n  &amp;lt;!-- configuration resource files custom for this config --&amp;gt;\r\n  &amp;lt;string name=&quot;resource.action.types&quot; value=&quot;action.types.xml&quot; \/&amp;gt;\r\n  ....\r\n&amp;lt;\/jbpm-configuration&amp;gt;\r\n<\/pre>\n<\/p>\n<p>\nSchlie\u00dflich 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\u00e4ter gebraucht).<\/p>\n<pre class=\"brush: xml; title: ; notranslate\" title=\"\">\r\n&lt;!-- jBPM configuration --&gt;\r\n&lt;bean id=&quot;jbpmConfiguration&quot; \r\n    class=&quot;org.springmodules.workflow.jbpm31.LocalJbpmConfigurationFactoryBean&quot;&gt;\r\n\t&lt;property name=&quot;configuration&quot; value=&quot;classpath:jbpm.cfg.xml&quot; \/&gt;\r\n\t....\r\n&lt;\/bean&gt;\r\n<\/pre>\n<\/p>\n<h3>Der Action-Handler<\/h3>\n<p>Fehlt noch der Action-Handler f\u00fcr die Spring-Action, der die SpringBean lokalisiert und durch delegiert. Hierzu benutzen wird den FactoryLocator aus den Spring-Modules ganz analog wie der JbpmHandlerProxy:<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\n    package rinke.solutions.jbpm;\r\n\r\n    import org.dom4j.Element;\r\n    import org.jbpm.graph.def.Action;\r\n    import org.jbpm.graph.def.ActionHandler;\r\n    import org.jbpm.graph.exe.ExecutionContext;\r\n    import org.jbpm.jpdl.xml.JpdlXmlReader;\r\n    import org.jbpm.jpdl.xml.Parsable;\r\n    import org.springframework.beans.factory.access.BeanFactoryReference;\r\n    import org.springmodules.workflow.jbpm31.JbpmFactoryLocator;\r\n\r\n    \/**\r\n    * Delegates a spring-action to the referenced spring bean\r\n    *\/\r\n    public class SpringActionSupport extends Action implements Parsable {\r\n\r\n      private static final long serialVersionUID = 1L;\r\n      \/**\r\n       * stores the name of the spring bean to delegate to.\r\n       *\/\r\n      private String beanname;\r\n\r\n      \/**\r\n       * executes the action. 1st the default BeanFactory is located (with JbpmFactoryLocator).\r\n       * 2nd the bean is located and delegated to.\r\n       *\/\r\n      public void execute(ExecutionContext executionContext) throws Exception {\r\n        JbpmFactoryLocator locator = new JbpmFactoryLocator();\r\n        BeanFactoryReference reference = locator.useBeanFactory(null);\r\n        ActionHandler springAction = (ActionHandler) reference.getFactory().getBean(beanname, ActionHandler.class);\r\n        springAction.execute(executionContext);\r\n        reference.release();\r\n      }\r\n\r\n      \/**\r\n       * read bean name from attribute\r\n       *\/\r\n      public void read(Element element, JpdlXmlReader jpdlReader) {\r\n        beanname = element.attributeValue(&quot;bean&quot;);\r\n      }\r\n\r\n      \/**\r\n       * not used\r\n       *\/\r\n      public void write(Element element) {\r\n      }\r\n\r\n    } \r\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Zwar gibt es mit den Spring-Modules bereits Support f\u00fcr 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\u00e4ndlich: Es muss also jedesmal der ProxyHandler hingeschrieben werden &hellip; <a href=\"https:\/\/cogito-ergo-blog.de\/blog\/2007\/10\/11\/spring-und-jbpm\/\">Weiterlesen <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[9],"tags":[],"_links":{"self":[{"href":"https:\/\/cogito-ergo-blog.de\/blog\/wp-json\/wp\/v2\/posts\/35"}],"collection":[{"href":"https:\/\/cogito-ergo-blog.de\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/cogito-ergo-blog.de\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/cogito-ergo-blog.de\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/cogito-ergo-blog.de\/blog\/wp-json\/wp\/v2\/comments?post=35"}],"version-history":[{"count":5,"href":"https:\/\/cogito-ergo-blog.de\/blog\/wp-json\/wp\/v2\/posts\/35\/revisions"}],"predecessor-version":[{"id":10032,"href":"https:\/\/cogito-ergo-blog.de\/blog\/wp-json\/wp\/v2\/posts\/35\/revisions\/10032"}],"wp:attachment":[{"href":"https:\/\/cogito-ergo-blog.de\/blog\/wp-json\/wp\/v2\/media?parent=35"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/cogito-ergo-blog.de\/blog\/wp-json\/wp\/v2\/categories?post=35"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/cogito-ergo-blog.de\/blog\/wp-json\/wp\/v2\/tags?post=35"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}