I am implementing some of my business logic in my facade layer (which does some calculations and makes calls to service layers etc). What is the recommended stereotype for this layer, similar to #Service on service layer ? I use #Component as of now. Is it worth creating a new annotation as I'm using the same pattern across multiple projects?
It depends on whether you need to implement some logic on all the facade methods. For example , suppose you need to apply an AOP aspect on all the facade methods , by making a new specific annotation for it , you can locate the correct facade methods and process them based on the presence of this new annotation rather than a hard-coded list.
The documentation also mentions it:
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. #Repository, #Service, and
#Controller can also carry additional semantics in future releases of
the Spring Framework. Thus, if you are choosing between using
#Component or #Service for your service layer, #Service is clearly the
better choice. Similarly, as stated earlier, #Repository is already
supported as a marker for automatic exception translation in your
persistence layer.
Here as Spring needs to locate all repository classes to apply an automatic exception translation for them , so it creates a new specific annotation #Repository.
Related
I'm working in a company where JPA #transactional are used within #Component beans. I've always been told that #Transactional should be used inside #Service beans. Does someone could explain spring mechanisms differences between those and what are the best pratctices .. and why
There is no difference.
Also, #Service and #Component are the same. #Service is just a stereotype that developers often use to indicate that the Spring Bean is kind of a Service (maybe in a DDD meaning or not)
First of all, there is no difference.
From the spring javadoc
#Component
Indicates that an annotated class is a "component". Such classes are considered candidates for auto-detection when using annotation-based configuration and classpath scanning.
...
#Transactional
Indicates that an annotated class is a "Service", originally defined by Domain-Driven Design (Evans, 2003) as "an operation offered as an interface that stands alone in the model, with no encapsulated state."
May also indicate that a class is a "Business Service Facade" (in the Core J2EE patterns sense), or something similar. This annotation is a general-purpose stereotype and individual teams may narrow their semantics and use it as appropriate.
This annotation serves as a specialization of #Component, allowing for implementation classes to be autodetected through classpath scanning.
Frankly speaking, they behave in the same way.
By using #Transactional annotation on a public method or class it simply creates a proxy with transaction code for you.
IMO great explanation of #Transactional
Spring Stereotype Annotations
Some of the examples on internet use #Transactional annotation on DAO implementation methods while some use this annotation for the service layer methods. Where is it more appropriate to put the #Transactional and why?
Similarly where to put #Repository annotation. On the DAO interface or on the DAO implementation?
I have always used #Service and #Repository annotations on their implementations, but they can be put in either one. Although, putting it on a interface would mean that you won't be able to have more than one implementation, because you would get a NoUniqueBeanDefinitionException error.
In the case of #Transactional, it depends, but normally it goes on the service. If you want to be able to add various DB calls on one transaction, then it should go in the service. If you want to make small transactions, then on the DAO would be best, but then, you wouldn't be able to modify several tables in one single transaction. Another con of having it on the DAO, is that you won't be able to rollback multiple modifications, only the ones that are bing executed by the DAO.
EDIT
After several projects using Spring, each one of different proportions, I end up changing my own practices. I would like to add that even though adding #Transactional to the service layer isn't exactly bad practice, it can be negatively affect the performance of the application. So in my own experience, it is better to add it to the DAO/Repository layers and only add at function level in the service layer, if a transaction must be atomic.
One more thing, if you are using Spring Data, the #Repository must be added on the interface. Only if you extend the JpaRepository will you need to add the #Repository annotation on the implementation. In this case, the interface of the JpaRepository and the custom implementation will both have #Repository.
Is this good practice to mark service class with annotation #service and #repository , since I am doing most of my DB operations in my service class. Does spring treats them a singleton class or prototype?
It makes easier for Spring to target pointcuts with more specific annotations. So, you should code DB operations in DAO layer and annotate it with #Repository as it causes exceptions to be wrapped up as DataAccessExceptions. Also, coding related stuff in it's own layer give rise to code modularity and reuse.
Moreover using the specialized annotations help to clearly demarcate application layers, in a standard 3 tier application.
Does spring treats them a singleton class or prototype?
By default all beans are of Singleton scope in Spring. To make it serve as prototype you have to change the scope of bean.
what if i don't annotate DAO classes with #Repository, will that still makes the unchecked exceptions (thrown from DAO methods) eligible for translation into Spring DataAccessException?? Can anyone expain this? bit confused with #Repository annotation
Definition of #Repository given on this link
Indicates that an annotated class is a "Repository", originally
defined by Domain-Driven Design (Evans, 2003) as "a mechanism for
encapsulating storage, retrieval, and search behavior which emulates a
collection of objects".
Teams implementing traditional J2EE patterns such as "Data Access
Object" may also apply this stereotype to DAO classes, though care
should be taken to understand the distinction between Data Access
Object and DDD-style repositories before doing so. This annotation is
a general-purpose stereotype and individual teams may narrow their
semantics and use as appropriate.
A class thus annotated is eligible for Spring DataAccessException
translation when used in conjunction with a
PersistenceExceptionTranslationPostProcessor. The annotated class is
also clarified as to its role in the overall application architecture
for the purpose of tooling, aspects, etc.
what if I don't annotate DAO classes with #Repository, will that still
makes the unchecked exceptions (thrown from DAO methods) eligible for translation into Spring DataAccessException??
No,Because as per details given on this link
Bean post-processor that automatically applies persistence exception
translation to any bean marked with Spring's #Repository annotation,
adding a corresponding PersistenceExceptionTranslationAdvisor to the
exposed proxy (either an existing AOP proxy or a newly generated proxy
that implements all of the target's interfaces).
Hope this will help you understand!!
I think both #Component and #Service can be used to detect bean automatically, anyone can show me the difference between those two annotations?
The basic difference between both annotations is that #Service is a specialization of #Component.
See also spring documentation for #Service:
Indicates that an annotated class is a "Service" (e.g. a business
service facade).
This annotation serves as a specialization of #Component, allowing for
implementation classes to be autodetected through classpath scanning.
A specialization of component is also a #Repository and a #Controller
Further information can be found e.g. here.
As of and up to Spring 3.1, there is no difference in the way that Spring handles them. The docs say this, but in a rather obscure way:
Spring 2.5 introduces further stereotype annotations: #Component, #Service, and #Controller. #Component is a generic stereotype for any Spring-managed component. #Repository, #Service, and #Controller are specializations of #Component for more specific use cases, for example, in the persistence, service, and presentation layers, respectively. 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. It is also possible that #Repository, #Service, and #Controller may carry additional semantics in future releases of the Spring Framework. 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.
So for now, #Service will be treated by Spring exactly the same as #Component, but #Service can be considered a form of documentation.
I'm not really sure why #Service was included in Spring 2.5 at all, since it doesn't seem to have any really purpose.
check the source code
#Target({ElementType.TYPE})
#Retention(RetentionPolicy.RUNTIME)
#Documented
#Component
public #interface Service {
/**
* The value may indicate a suggestion for a logical component name,
* to be turned into a Spring bean in case of an autodetected component.
* #return the suggested component name, if any
*/
String value() default "";
}
Service annotation is in turn annotated with #Component . There's nothing much in difference .
here is the explanation to why we need such specialisation...
In Spring 2.0 and later, the #Repository annotation is a marker for any class that
fulfills the role or stereotype (also known as Data Access Object or DAO) of a repository. Among the uses of this marker is the automatic translation of exceptions.
Spring 2.5 introduces further stereotype annotations: #Component, #Service, and #Controller. #Component is a generic stereotype for any Spring-managed component. #Repository, #Service, and #Controller are specializations of #Component for more specific use cases, for example, in the persistence, service, and presentation layers, respectively.
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.