cancel
Showing results for 
Search instead for 
Did you mean: 

Next steps for the spring component integration

tombaeyens
Champ in-the-making
Champ in-the-making
[27/02/11 12:47:23] Josh Long: ive officially got 70% of what i wanted to support in the component code for the Spring module working. i wondered if i might talk to you about the last 30% 🙂
[27/02/11 12:54:39] Josh Long: at the moment, there is support for:

1) Activiti POJOs:

class CustomerService {
   @StartProcess('customer-fulfillment')
   public  void enrollCustomer(@ProcessVariable('customerId') long customerId) { … }
}

..

@Autowired private CustomerService cs ;
// …
cs.enrollCustomer( 232) ; // automatically launches a ProcessInstance

2) scoped beans

@Scoped('process") Foo foo ; //the bean is created and destroyed on process instance lifecycle demarcations

Inside of Foo, i imght have the following declaration:

// injects the current process instance 'customerId'
@Value( "#{ processVariables['customerId'] }")
private long customerId;

I can also do:

@Autowired private ProcessInstance processInstance ;

in any bean - scoped or not. its injects a proxy so that, even if the containg bean is not scoped, the methods called on the ProcessInstance are to the currently active, scoped ProcessInstance and so it is threadsafe.

[27/02/11 12:59:41] Josh Long: let me know when youre free - i want to talk about the possibility of having serviceTasks that delegate to a single registered instance so that i could simply write:

<serviceTask id="notifyCustomer" />

and, since no bean is explicitly configured, a default bean gets invoked and that bean, in my case, is a Spring handler that would look at the fact that the
<serviceTask> is named 'notifyCustomer' and would look for a POJO that has

@ActivitiMapping(serviceTask ='notifyCustomer')
public void myCustomServiceTaskHandlerMethod ( @ProcessVariable('customerId') long customerId) {
   // ..
}

and would automatically call it
4 REPLIES 4

jbarrez
Star Contributor
Star Contributor
Awesome progress. Really powerful stuff, Josh!

joshlong
Champ in-the-making
Champ in-the-making
Thanks guys. My intent wasn't to get priase, however. I want to get help implementing the last part in activiti core. Basically, i want to enable service  tasks that dont have an activiti:delegate or anything, theyre empty:

<serviceTask id = "enroll-customer" />
I want to setup the ProcessEngine to then attempt to look up the correct handler (like a 'default' handler  JavaDelegate o ReceiveTaskActivity ).

The idea is that the default ReceiveTaskActivity would then be pluggable. For Activiti-Spring module, you could have a dispatcher that invokes beans in the Spring context that have annotations that 'register' them to the state as handlers:

@ActivitiMapping( serviceTask = 'enroll-customer')
public void handleEnrollCustomerTask() { }

or

@ActivitiMapping( serviceTask = 'enroll-customer')
public void handleEnrollCustomerTask(  @ProcessVariable( "customerId") Long customerId ) { }

or

@ActivitiMapping( serviceTask = 'enroll-customer')
public void handleEnrollCustomerTask(  @ProcessInstance ProcessInstance pi,
                                                 @ProcessVariable( "customerId") Long customerId ) { }

etc.

These methods would be invoked automatically and enlisted to handle the service task and other things. T

This extension mechanism would of course be useful to anybody building on top of Activiti (Spring, CDI, … anybody!).

Right now, I already have basic support for explicitly defining a 'registry' that handles the mapping to those beans with those kinds of annotations, but to use it u must do:

<serviceTask id="enroll-customer" name="enroll-customer"
           activiti:delegateExpression="#{registry}"/>
etc.

You might ahve a sophisticated business process with 10 serviceTasks and their 'delegateExpression' would all be '#{registry}'! It's ugly…

Your feedback is very appreciated.

tombaeyens
Champ in-the-making
Champ in-the-making
@ActivitiMapping( serviceTask = 'enroll-customer')
public void handleEnrollCustomerTask(  @ProcessInstance ProcessInstance pi,
                                                 @ProcessVariable( "customerId") Long customerId ) { }

The idea makes perfect sense and totally rocks.

We should not bind this automagically to a serviceTask.  This behavior should be marked clearly with an activity type like this:

<serviceTask id="enroll-customer" activiti:type="spring-annotation-mapping">
Do you think that is a good solution too, Josh?

meyerd
Champ on-the-rise
Champ on-the-rise
Hi,

Well in the spirit of the Inversion of Control Pattern I think Josh's Proposal goes in the right direction. It depends on your perspective of course: "who is controlling whom?".
If you have the perspective that a process should contain as few technical details as possible, then it makes a lot of sense, because then you are building an Environment in which the process can run, leaving open the possibility to change that environment (ie. add different beans etc).

If the process.bpmn20.xml is you primary focus, then I would  agree that sth. like

<serviceTask id="enroll-customer" activiti:type="spring-annotation-mapping">
or even

<serviceTask id="enroll-customer" name="enroll-customer" activiti:delegateExpression="#{…}"/>

Makes more sense.

Daniel