Field injection into Spring beans - bad idea?

In Camunda, I use delegate expressions for service task and listeners to specify that I want to execute a Spring bean to handle that task or event. Spring beans are singletons by default. I also read Camunda docs about field injection. From it, I read the following:

The injection happens each time the service task is called since a separate instance of the class will be created. When the fields are altered by your code, the values will be re-injected when the activity is executed next time.

This is not the case with Spring beans unless Camunda does some magic. And also:

Private fields cannot always be modified! It does not work with e.g., CDI beans (because you have proxies instead of real objects) or with some SecurityManager configurations.

The latter might read like it is OK to use this pattern with CDI beans, just handle the case with private fields correctly.

My point/question is:
I think that field injection can’t be used with Spring beans because it will fail when the bean is concurrently used. I think that the documentation should state that explicitly. Am I missing something? Does Camunda somehow handle this case? Is it mentioned somewhere in the docs and I have missed it?

2 Likes

Hi @Infeligo,

good catch! I agree that you should not use field injection with Spring beans (usually).

Do you want to add a hint to the documentation?

Best regards,
Philipp

1 Like

@Yana would be good to get this added into the docs!

1 Like

I made a PR with a note about this issue and it got merged:
https://docs.camunda.org/manual/7.10/user-guide/process-engine/delegation-code/#field-injection

This note is in the end of the section and I don’t know if this is visible enough.

3 Likes

Ah ! Great. Did not see it.

It’s too bad it does not work, as FI would be great usage with spring beans when using execution and task listeners, so you can “configure” with arguments, rather than having to type it all into a expression.

1 Like

Hi Philipp,

Does this work if we define the delegate expressions with @Scope(value=“prototype”) . Reason to use this approach is i have other autowired items in my delegate expression and this approach helps in reducing the customization needed .

In my testing if the delegate expression was singelton the injected values were getting overriden but with scope prototype i dont see the inject values getting overwritten as it creates a new instance every time . Let me know your thoughts .

Thanks
Dinesh

6 Likes

But, as i can see by testing @Scope(value=“prototype”) resolves this issue. And without addition lack of performance – because Camunda still creates new instances of a class that is not a bean

Or are there any other problems, @StephenOTT @Philipp_Ossler ?