Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is this design of Spring singleton beans thread safe?

Tags:

Consider the following Spring Service class. The spring scope defined is Singleton. The two service beans auto-wired as fields in the class below have similar structure - they too are composed of fields which are either of the following

  • Spring beans themselves
  • stateless classes
  • immutable classes

and so on. This pattern is overall used in the application design.

@Service      public class DocumentService {     private final DocumentGenerationService documentGenerationService;   private final DocumentPublishService documentPublishService;    @Autowired   public DocumentService (DocumentGenerationService documentGenerationService,                               DocumentPublishService documentPublishService) {   this.documentGenerationService = documentGenerationService;   this.documentPublishService = documentPublishService; }  ... methods follow 

Is it correct to say that the DocumentService class is immutable since it's not possible to mutate any of its two fields (which are spring beans that can be initialized only once by the container itself)?

In any case, can the DocumentService bean as defined above be considered thread-safe? And if this design is followed the application as a whole is thread-safe too?

like image 684
haps10 Avatar asked Jun 21 '11 01:06

haps10


2 Answers

Is it correct to say that the DocumentService class is immutable since it's not possible to mutate any of its two fields (which are spring beans that can be initialized only once by the container itself)?

According to the definition of immutability, and formally speaking, this class is NOT immutable.

An object is immutable if it is not possible to change the state of the object, and the state of documentGenerationService and documentPublishService is part of the state of the class DocumentService.

And, as a result, if the class has always the same state, it behaves always the same way. In other words, there is no way to change the behaviour of an immutable object because the behaviour of an object depends only in its state, and in an immutable object, this state never changes (examples of immutable objects are Strings and Integers).

Note that in the definition of immutability we find an exception where "an object is considered immutable even if some [...] attributes change but the object's state [and, therefore, behaviour] appears to be unchanging [...]", but in this case (with the information provided) a change in the state of the references could definitely change the behaviour of the class (since we don't have any control on their own internal state).

There is a strategy to make a class immutable. You already follow some of its guidelines, but in case you wished to do it immutable (I think it is not the case) you would need some others like make "defensive copy" of the arguments that you receive in the constructor and avoid subclasses overriding methods.

This link is also interesting.

Nevertheless, you should not make Spring beans immutable, since it is not the way to use the programming model that Spring offers. So, in this case, it is "good" that the class is not immutable.

In any case, can the DocumentService bean as defined above be considered thread-safe?

As declared here, this class IS thread safe. Many threads can safely access this class without any race condition arising. We cannot say the same about the fields it contains, but this class is thread-safe. This works just the same way as "thread-safe list": it can contain "no thread-safe" objects, but still be a "thread-safe list".

And if this design is followed the application as a whole is thread-safe too?

If all the classes of your system are thread-safe (i.e. not a single race condition appears anywhere) you could informally say that the application is thread safe.

like image 125
Mr.Eddart Avatar answered Oct 26 '22 12:10

Mr.Eddart


Spring doesn't guarantee thread-safety. That's your responsibility.

All private member variables are shared. They might be final, but that only means that the references can't be changed. Any mutable state must be synchronized. If they're indeed immutable, then I think you're on solid ground.

I agree with the comment about autowiring dependencies. I would leave those under Spring's control if possible.

like image 21
duffymo Avatar answered Oct 26 '22 12:10

duffymo