Spring Beans in Processes
Limit the exposed Spring Beans
When using the ProcessEngineFactoryBean
, by default, all expressions and scripts in the BPMN processes will also “see” all the Spring beans. It’s possible to limit the beans you want to expose or even expose no beans at all using a map that you can configure. The example below exposes a single bean (printer), available to use under the key printer
. To expose NO beans at all, pass an empty map as beans
property on the SpringProcessEngineConfiguration
. When no beans
property is set, all Spring beans in the context will be available.
<bean id="processEngineConfiguration"
class="org.camunda.bpm.engine.spring.SpringProcessEngineConfiguration">
...
<property name="beans">
<map>
<entry key="printer" value-ref="printer" />
</map>
</property>
</bean>
<bean id="printer"
class="org.camunda.bpm.engine.spring.test.transaction.Printer" />
Using Spring Beans in expressions
The exposed beans can be used in expressions. For example, the SpringTransactionIntegrationTest
testBasicActivitiSpringIntegration.bpmn20.xml
shows how a method on a Spring bean can be invoked using a UEL method expression:
<definitions id="definitions" ...>
<process id="helloProcess" isExecutable="true">
<startEvent id="start" />
<sequenceFlow id="flow1" sourceRef="start" targetRef="print" />
<serviceTask id="print"
camunda:expression="#{printer.printMessage(execution)}" />
<sequenceFlow id="flow2" sourceRef="print" targetRef="userTask" />
<userTask id="userTask" />
<sequenceFlow id="flow3" sourceRef="userTask" targetRef="end" />
<endEvent id="end" />
</process>
</definitions>
Where Printer looks like this:
public class Printer {
public void printMessage(ActivityExecution execution) {
execution.setVariable("myVar", "Hello from Printer!");
}
}
And the Spring bean configuration (also shown above) looks like this:
<beans ...>
...
<bean id="printer"
class="org.camunda.bpm.engine.spring.test.transaction.Printer" />
</beans>
Expression resolving with the shared process engine
In a shared process engine deployment scenario, you have a process engine which dispatches to multiple applications. In this case, there is not a single Spring application context but each application may maintain its own application context. The process engine cannot use a single expression resolver for a single application context but must delegate to the appropriate process application, depending on which process is currently being executed.
This functionality is provided by the org.camunda.bpm.engine.spring.application.SpringProcessApplicationElResolver
. This class is a ProcessApplicationElResolver
implementation delegating to the local application context. Expression resolving then works in the following way:
- The shared process engine checks which process application corresponds to the process it is currently executing.
- It then delegates to that process application for resolving expressions.
- The process application delegates to the
SpringProcessApplicationElResolver
which uses the local Spring application context for resolving beans.
The SpringProcessApplicationElResolver
class is automatically detected if the camunda-engine-spring
module is included as a library of the process application, not as a global library.
Using Spring Beans in scripting
When using ProcessEngineFactoryBean
, all Spring beans are accessible in Groovy, JavaScript, and Jython. For example, the ScriptTaskTest-applicationContext.xml
exposes the bean ’testbean':
<beans ...>
...
<bean id="testbean"
class="org.camunda.bpm.engine.spring.test.scripttask.Testbean" />
</beans>
Where Testbean looks like this:
@Component
public class Testbean {
private String name = "name property of testbean";
public String getName() {
return name;
}
}
Testbean
is referenced then form JavaScript:
execution.setVariable('foo', testbean.name);