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 t
Spring doesn't guarantee thread-safety, when it says beans are singleton. If you make bean of singleton scope in spring, it simply mean that a single object instance per Spring IoC container is created. But still that singleton-scoped bean class may not be thread safe in itself, so its programmer's responsibility to make the code thread safe.
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.
You can put the @Autowired annotation on top of the services instead of using them in the constructor. It's a Spring managed bean which means it's a singleton. It is thread safe, but that depends on the implementation.
@Service
public class DocumentService {
@Autowired
private DocumentGenerationService documentGenerationService;
@Autowired
private DocumentPublishService documentPublishService;
... methods follow
The example code shown in your question is definitely thread-safe.
However, the code needs to be considered in the context of the whole application. For instance, the code above does not provide any guarantees about the thread safety of the objects referred to by the documentGenerationService
and documentPublishService
attributes. If they are not adequately synchronized, then code that uses them (including other methods of this class) may not be thread-safe.
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.
Your code looks thread-safe. Spring doesn't guarantee thread-safety, when it says beans are singleton. If you make bean of singleton scope in spring, it simply mean that a single object instance per Spring IoC container is created. But still that singleton-scoped bean class may not be thread safe in itself, so its programmer's responsibility to make the code thread safe.
In your code, documentGenerationService
for instance is final. That guarantees that references cannot change, and also from new Java Memory model, instantiation is guaranteed. But @duffymo said, the objects being referred must be immutable as well.
Rest all is good :)