Enterprise Java

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

Before you learn the difference between @Component, @Service, @Controller, and @Repository annotations in Spring framework, it’s important to understand the role of @Component annotation in Spring. During 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 register classes as Spring bean which is annotated using @Component annotation. This means you don’t to declare that bean using the <bean&gt; 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 which are annotated using @Controller but not with @Component.

This means @Component and @Controller are 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,

Same is true for @Service and @Repository annotation, they are a specialization of @Component in service and persistence layer. A Spring bean in service layer should be annotated using @Service instead of @Component annotation and a spring bean in 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 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.

Summary

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 persistence layer.
  3. @Service is a stereotype for the service layer.
  4. @Controller is a stereotype for presentation layer (spring-MVC).

And here is the nice diagram to explain the hierarchy of all these annotations in Spring Framework:

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 controller. Similarly, @Service is used to annotated classes which hold business logic in the Service layer and @Repository is used in Data Access layer.

You can read more about component scanning and how Spring framework automatically detects bean in Spring fundamentals course by Bryna 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.

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 with your friends and colleagues. If you have any question or feedback then please drop a note.

Published on Java Code Geeks with permission by Javin Paul, partner at our JCG program. See the original article here: Difference between @Component, @Service, @Controller, and @Repository in Spring

Opinions expressed by Java Code Geeks contributors are their own.

Javin Paul

I have been working in Java, FIX Tutorial and Tibco RV messaging technology from past 7 years. I am interested in writing and meeting people, reading and learning about new subjects.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

1 Comment
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
eduardo
eduardo
4 years ago

Great article!

Back to top button