Before you learn the difference between @Component, @Service, @Controller, and @Repository annotations in the Spring framework, it's important to understand the role of @Component annotation in Spring. During the initial release of Spring, all beans are used to be declared in an XML file. For a large project, this quickly becomes a massive task, and Spring guys recognize the problem rather quickly. In later versions, they provide annotation-based dependency injection and Java-based configuration. From Spring 2.5 annotation-based dependency injection was introduced, which automatically scans and registers classes as Spring bean which is annotated using @Component annotation.
This means you don't declare that bean using the <bean> tag and inject the dependency, it will be done automatically by Spring. This functionality was enabled and disabled using <context:component-scan> tag.
Now that you know what does @Component annotation does let's see what does @Service, @Controller, and @Repository annotation do.
They are nothing but the specialized form of @Component annotation for certain situations. Instead of using @Component on a controller class in Spring MVC, we use @Controller, which is more readable and appropriate. Similarly for REST based application, you can use @RestController annotation which is more appropriate for RESTful web services.
By using that annotation we do two things, first, we declare that this class is a Spring bean and should be created and maintained by Spring ApplicationContext, but also we indicate that its a controller in MVC setup. This latter property is used by web-specific tools and functionalities.
For example, DispatcherServlet will look for @RequestMapping on classes that are annotated using @Controller but not with @Component.
This means @Component and @Controller are the same with respect to bean creation and dependency injection but later is a specialized form of former.
This means you don't declare that bean using the <bean> tag and inject the dependency, it will be done automatically by Spring. This functionality was enabled and disabled using <context:component-scan> tag.
Now that you know what does @Component annotation does let's see what does @Service, @Controller, and @Repository annotation do.
They are nothing but the specialized form of @Component annotation for certain situations. Instead of using @Component on a controller class in Spring MVC, we use @Controller, which is more readable and appropriate. Similarly for REST based application, you can use @RestController annotation which is more appropriate for RESTful web services.
By using that annotation we do two things, first, we declare that this class is a Spring bean and should be created and maintained by Spring ApplicationContext, but also we indicate that its a controller in MVC setup. This latter property is used by web-specific tools and functionalities.
For example, DispatcherServlet will look for @RequestMapping on classes that are annotated using @Controller but not with @Component.
This means @Component and @Controller are the same with respect to bean creation and dependency injection but later is a specialized form of former.
Even if you replace @Controller annotation with @Compoenent, Spring can automatically detect and register the controller class but it may not work as you expect with respect to request mapping.
The same is true for @Service and @Repository annotation, they are a specialization of @Component in service and persistence layer. A Spring bean in the service layer should be annotated using @Service instead of @Component annotation and a spring bean in the persistence layer should be annotated with @Repository annotation.
By using a specialized annotation we hit two birds with one stone. First, they are treated as Spring bean, and second, you can put special behavior required by that layer.
For example, @Repository's not only helping in annotation based configure but also catch Platform-specific exceptions and re-throw them as one of Spring’s unified unchecked exception.
Though for that you also need to declare org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor as Spring bean in your application context.
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 rethrown as one of Spring’s unchecked data access exceptions.
The same is true for @Service and @Repository annotation, they are a specialization of @Component in service and persistence layer. A Spring bean in the service layer should be annotated using @Service instead of @Component annotation and a spring bean in the persistence layer should be annotated with @Repository annotation.
By using a specialized annotation we hit two birds with one stone. First, they are treated as Spring bean, and second, you can put special behavior required by that layer.
For example, @Repository's not only helping in annotation based configure but also catch Platform-specific exceptions and re-throw them as one of Spring’s unified unchecked exception.
Though for that you also need to declare org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor as Spring bean in your application context.
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 rethrown as one of Spring’s unchecked data access exceptions.
This is also one of the frequently asked Spring Interview Question and a popular concept from the Spring certification perspective. You will find a couple of questions based on these annotations and their usage in the Spring professional certification exam too.
How does Component Scanning work in Spring?
From Spring 2.0, Spring provides <context:component-scan> and annotation-driven dependency injection to automatically detect and register Spring bean instead of specifying them in the XML file.But, it 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.
They are scanned because they themselves are annotated with @Component annotation. If you define your own custom annotation and annotate it with @Component, then it will also get scanned with <context:component-scan>.
If you want to learn more about dependency injection, auto-wiring, and different types of configuration in Spring e.g. XML based, annotation-based, and Java configuration in Spring, the documentation of Spring is really great resource.
Difference between @Component, @Service, @Controller, and @Repository in Spring
Here is a nice summary of what does @Component, @Service, @Controller, and @Repository annotation do in Spring Framework:- @Component is a generic stereotype for any Spring-managed component or bean.
- @Repository is a stereotype for the persistence layer.
- @Service is a stereotype for the service layer.
- @Controller is a stereotype for the presentation layer (spring-MVC).
That's all about the difference between @Component, @Controller, @Service, and @Repository in Spring Framework. As I said, all of them are used to auto-detect Spring beans when context scanning is enabled and essentially provide the same functionality with respect to dependency injection.
Their only difference comes in their purpose i.e. @Controller is used in Spring MVC to define controller, which are first Spring bean and then the controller. Similarly, @Service is used to annotated classes that hold business logic in the Service layer and @Repository is used in the Data Access layer.
In short, you should use the most appropriate annotation based upon which layer that particular class belongs to.
Other Spring Framework articles and interview questions you may like
- 3 ways to learn Spring framework for beginners
- 10 Free courses to learn Spring Boot in depth
- How Spring MVC works internally?
- Difference between @RequestParam and @PathVariable in Spring MVC?
- 5 Free Courses to learn Spring and Spring Boot
- 3 Ways to return content from Spring Controller?
- How to enable Spring security in a Java web application?
- Top 20 Spring Boot Interview Questions
- 10 Advanced Spring Boot Courses for Experienced Programmers
- 5 Courses to learn Spring Cloud and Microservices
- Top 5 Courses to become a full-stack Java developer
- Difference between @RequestMapping and @GetMapping?
- 10 Frameworks you can learn as full-stack Developers.
Excellent
ReplyDeleteWhen do we use @Bean?
ReplyDelete@Bean is a method annotation. You define it on a method in a configuration class, which is annotated with @Configuration
DeleteOne example is when you want to use or create objects of 3rd paty libraries.
ReplyDeleteDispatcherSerlvlet doesn't look for @Controller. Any bean that has @RequestMapping is handled as a request handler. There is even an issue about it: https://github.com/spring-projects/spring-framework/issues/22154
ReplyDeleteAnswers about annotation types is very poor, all I can get from what you wrote is that annotations are different. Nothing more, no examples, co concrete information.
ReplyDelete