Can the specialised variants of Spring's @Component be inappropriately used? i.e. if I call my service class @Repository instead of @Service or the reverse. Is there any safeguards against such inappropriate use or is it just a recommendation that they be used correctly as per context without any enforcement from Spring?
Could some one please let me know what exactly happens with each Stereotype?I read the javadocs and don't fully understand what specialised set of features does each of Spring Stereotype offers
Yes, you can annotate any class with @Repository
or @Service
, and both of them will behave the same but here comes the interesting point from documentation:
Therefore, you can annotate your component classes with @Component, but by annotating them with @Repository, @Service, or @Controller instead, your classes are more properly suited for processing by tools or associating with aspects. For example, these stereotype annotations make ideal targets for pointcuts.
Thus, if you are choosing between using @Component or @Service for your service layer, @Service is clearly the better choice. Similarly, as stated above, @Repository is already supported as a marker for automatic exception translation in your persistence layer.
Here you can see two important things being discussed Ideal target for pointcuts in the first para and 2nd one as automatic exception translation
Clearly, 1st one is understandable if you are aware of AOP and second one is one beautiful thing about these annotations. Lets see the docs what does automatic exception translation mean:
Common data access exceptions. Spring can wrap exceptions from your O/R mapping tool of choice, converting them from proprietary (potentially checked) exceptions to a common runtime DataAccessException hierarchy. This allows you to handle most persistence exceptions, which are non-recoverable, only in the appropriate layers, without annoying boilerplate catches/throws, and exception declarations. You can still trap and handle exceptions anywhere you need to. Remember that JDBC exceptions (including DB specific dialects) are also converted to the same hierarchy, meaning that you can perform some operations with JDBC within a consistent programming model.
So basically, they are same, but they differ a little when you dig deep. Hope you got it.
for example, if we annotate all the classes with @Service
annotation, all of these classes will be registered in the container but how things will differ. See, if you annotate some class with @Repository
annotation, the postprocessor automatically looks for all exception translators (implementations of the PersistenceExceptionTranslator interface) and advises all beans marked with the @Repository annotation so that the discovered translators can intercept and apply the appropriate translation on the thrown exceptions.
So, again, it is all about some sort of exception handling. Now, if you annotate the class with @Service
annotation rather than @Repository
annotation, the required translators will not get discovered.
Now regarding @Service annotation. This annotation doesn't bring more to the table than @Component. They are same, the only difference is @Service annotation is a specialization of @Component , and the only specialization it adds according to the docs is
This annotation is a general-purpose stereotype and individual teams may narrow their semantics and use as appropriate. Hence, @Service just adds more understanding than @Component.
So, at the end, we came to know that all are nearly same with slight differences where @Repository annotations has some more benefits in case of DAO class.