Can @Component, @Repository and @Service annotations be used interchangeably in Spring or do they provide any particular functionality besides acting as a notation device?
Repository and Service are children of Component annotation. So, all of them are Component. Repository and Service just expand it. How exactly? Service has only ideological difference: we use it for services. Repository has particular exception handler.
@Repository @Service and @Controller are serves as specialization of @Component for more specific use on that basis you can replace @Service to @Component but in this case you loose the specialization.
1. **@Repository** - Automatic exception translation in your persistence layer.
2. **@Service** - It indicates that the annotated class is providing a business service to other layers within the application.
Explanation of stereotypes :
@Service
- Annotate all your service classes with @Service. This layer knows the unit of work. All your business logic will be in Service classes. Generally methods of service layer are covered under transaction. You can make multiple DAO calls from service method, if one transaction fails all transactions should rollback.@Repository
- Annotate all your DAO classes with @Repository. All your database access logic should be in DAO classes.@Component
- Annotate your other components (for example REST resource classes) with component stereotype.@Autowired
- Let Spring auto-wire other beans into your classes using @Autowired annotation. @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.
Originally answered here.
Technically @Controller
, @Service
, @Repository
are all same. All of them extends @Component
.
From the Spring source code:
Indicates that an annotated class is a "component". Such classes are considered as candidates for auto-detection when using annotation-based configuration and classpath scanning.
We can directly use @Component
for each and every bean, but for better understanding and maintainability of a large application, we use @Controller
, @Service
, @Repository
.
Purpose of each annotation:
@Controller
-> Classes annotated with this, are intended to receive a request from the client side. The first request comes to the Dispatcher Servlet, from where it passes the request to the particular controller using the value of @RequestMapping
annotation.@Service
-> Classes annotated with this, are intended to manipulate data, that we receive from the client or fetch from the database. All the manipulation with data should be done in this layer.@Repository
-> Classes annotated with this, are intended to connect with database. It can also be considered as DAO(Data Access Object) layer. This layer should be restricted to CRUD (create, retrieve, update, delete) operations only.
If any manipulation is required, data should be sent be send back to @Service layer.If we interchange their place(use @Repository
in place of @Controller
), our application will work fine.
The main purpose of using three different @annotations
is to provide better Modularity to the Enterprise application.
Difference between @Component, @Repository, @Controller & @Service annotations
@Component – generic and can be used across application.
@Service – annotate classes at service layer level.
@Controller – annotate classes at presentation layers level, mainly used in Spring MVC.
@Repository – annotate classes at persistence layer, which will act as database repository.
@Controller
= @Component ( Internal Annotation ) + Presentation layer Features
@Service
= @Component ( Internal Annotation ) + Service layer Features
@Component
= Actual Components ( Beans )
@Repository
= @Component ( Internal Annotation ) + Data Layer Features ( use for handling the Domain Beans )
In order to simplify this illustration, let us consider technicality by use case, These annotations are used to be injected and as I said literally "Used to be injected" , that mean, if you know how to use Dependency Injection "DI" and you should, then you will always look for these annotations, and by annotating the classes with these Stereo Types, you are informing the DI container to scan them to be ready for Injection on other places, this is the practical target.
Now lets move to each one; first @Service, If you are building some logic for specific business case you need to separate that in a place which will contain your business logic, this service is normal Class or you can use it as interface if you want , and it is written like this
@Service
public class Doer {
// Your logic
}
// To use it in another class, suppose in Controller
@Controller
public class XController {
// You have to inject it like this
@Autowired
private Doer doer;
}
All are the same way when you inject them, @Repository it's an interface which apply the implementation for the Repository Pattern Repository design pattern, generally it's used when you are dealing with some data store or database, and you will find that, it contains multiple ready implementation for you to handle database operations; it can be CrudRepository, JpaRepository etc.
// For example
public interface DoerRepository implements JpaRepository<Long, XEntity> {}
Finally the @Component, this is the generic form for registered beans in Spring, that's spring is always looking for bean marked with @Component to be registered, then both @Service and @Repository are special cases of @Component, however the common use case for component is when you're making something purely technical not for covering direct business case! like formatting dates or handing special request serialization mechanism and so on.