Java – What’s the difference between @Component, @Repository & @Service annotations in Spring?
From Spring Documentation:
The
@Repository
annotation is a marker for any class that fulfils the role or stereotype of a repository (also known as Data Access Object or DAO). Among the uses of this marker is the automatic translation of exceptions, as described in Exception Translation.Spring provides 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 (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.
@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.
┌──────────────┬─────────────────────────────────────────────────────┐
│ Annotation │ Meaning │
├──────────────┼─────────────────────────────────────────────────────┤
│ @Component │ generic stereotype for any Spring-managed component │
│ @Repository │ stereotype for persistence layer │
│ @Service │ stereotype for service layer │
│ @Controller │ stereotype for presentation layer (spring-mvc) │
└──────────────┴─────────────────────────────────────────────────────┘
@Component
This is a general-purpose stereotype annotation indicating that the class is a spring component.
What’s special about @Component<context:component-scan>
only scans @Component
and does not look for @Controller
, @Service
and @Repository
in general. They are scanned because they themselves are annotated with @Component
.
Just take a look at @Controller
, @Service
and @Repository
annotation definitions:
@Component
public @interface Service {
….
}
@Component
public @interface Repository {
….
}
@Component
public @interface Controller {
…
}
Thus, it’s not wrong to say that @Controller
, @Service
and @Repository
are special types of @Component
annotation. <context:component-scan>
picks them up and registers their following classes as beans, just as if they were annotated with @Component
.
Special type annotations are also scanned, because they themselves are annotated with @Component
annotation, which means they are also @Component
s. If we define our own custom annotation and annotate it with @Component
, it will also get scanned with <context:component-scan>
@Repository
This is to indicate that the class defines a data repository.
What’s special about @Repository?
In addition to pointing out, that this is an Annotation based Configuration, @Repository
’s job is to catch platform specific exceptions and re-throw them as one of Spring’s unified unchecked exception. For this, we’re provided with PersistenceExceptionTranslationPostProcessor
, that we are required to add in our Spring’s application context like this:
<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>
This bean post processor adds an advisor to any bean that’s annotated with @Repository
so that any platform-specific exceptions are caught and then re-thrown as one of Spring’s unchecked data access exceptions.
@Controller
The @Controller
annotation indicates that a particular class serves the role of a controller. The @Controller
annotation acts as a stereotype for the annotated class, indicating its role.
What’s special about @Controller?
We cannot switch this annotation with any other like @Service
or @Repository
, even though they look same. The dispatcher scans the classes annotated with @Controller
and detects methods annotated with @RequestMapping
annotations within them. We can use @RequestMapping
on/in only those methods whose classes are annotated with @Controller
and it will NOT work with @Component
, @Service
, @Repository
etc…
Note: If a class is already registered as a bean through any alternate method, like through @Bean
or through @Component
, @Service
etc… annotations, then @RequestMapping
can be picked if the class is also annotated with @RequestMapping
annotation. But that’s a different scenario.
@Service
@Service
beans hold the business logic and call methods in the repository layer.
What’s special about @Service?
Apart from the fact that it’s used to indicate, that it’s holding the business logic, there’s nothing else noticeable in this annotation; but who knows, Spring may add some additional exceptional in future
Leave a Reply