Preparing for Java and Spring Boot Interview?

Join my Newsletter, its FREE

Friday, May 3, 2024

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 @Controllerwhich 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. 

@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. 

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:

public @interface Service {

public @interface Repository {

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

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.

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


Unknown said...


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.

remal said...

DispatcherSerlvlet doesn't look for @Controller. Any bean that has @RequestMapping is handled as a request handler. There is even an issue about it:

pg7812 said...

Answers 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.

Unknown said...

@Bean is a method annotation. You define it on a method in a configuration class, which is annotated with @Configuration

Post a Comment