Saturday, June 13, 2020

Difference between @Component, @Service, @Controller, and @Repository in Spring

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.

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. You can further see, Spring Master Class course on Udemy for more details about these annotations.

@Component vs  @Service vs  @Controller, and @Repository annotation in Spring


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. You can also see Spring Framework 5: Beginner to Guru on Udemy for more details.

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, I suggest you take the Spring Fundamentals course on Pluralsight. A free trial is also available.

Difference between @Component, @Service, @Controller, and @Repository in Spring


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:
  1. @Component is a generic stereotype for any Spring-managed component or bean. 
  2. @Repository is a stereotype for the persistence layer.
  3. @Service is a stereotype for the service layer.
  4. @Controller is a stereotype for the presentation layer (spring-MVC).
And here is the nice diagram to explain the hierarchy of all these annotations in Spring Framework:

Difference between @Component, @Service, @Controller, and @Repository in Spring


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.

You can read more about component scanning and how the Spring framework automatically detects bean in the Spring Framework: Spring Fundamentals by Bryan Hassen on Pluralsight. You can get it free for 10 days as well.

In short, you should use the most appropriate annotation based upon which layer that particular class belongs to.

Further Learning
Spring Framework 5: Beginner to Guru
Spring in Action by Craig Walls


Other Spring Framework articles and interview questions you may like

Thanks for reading this article so far. If you like this article then please share it with your friends and colleagues. If you have any questions or feedback then please drop a note.

P. S. - If you are looking for an online training course to learn Spring 5.1 and Spring Boot 2.1 from scratch, in a guided, code-focused way. then you can also take a look at the Learn Spring: The Master Class course by Eugen Paraschive of Baeldung. One of the most up-to-date courses to learn Spring.

3 comments :

Unknown said...

Excellent

erprtkjn said...

When do we use @Bean?

ENZO RIO said...

One example is when you want to use or create objects of 3rd paty libraries.

Post a Comment