What's the difference between @Component, @Repository & @Service annotations in Spring?

Viewed 1072686

Can @Component, @Repository and @Service annotations be used interchangeably in Spring or do they provide any particular functionality besides acting as a notation device?

In other words, if I have a Service class and I change the annotation from @Service to @Component, will it still behave the same way?

Or does the annotation also influence the behavior and functionality of the class?

30 Answers

@Component: you annotate a class @Component, it tells hibernate that it is a Bean.

@Repository: you annotate a class @Repository, it tells hibernate it is a DAO class and treat it as DAO class. Means it makes the unchecked exceptions (thrown from DAO methods) eligible for translation into Spring DataAccessException.

@Service: This tells hibernate it is a Service class where you will have @Transactional etc Service layer annotations so hibernate treats it as a Service component.

Plus @Service is advance of @Component. Assume the bean class name is CustomerService, since you did not choose XML bean configuration way so you annotated the bean with @Component to indicate it as a Bean. So while getting the bean object CustomerService cust = (CustomerService)context.getBean("customerService"); By default, Spring will lower case the first character of the component – from ‘CustomerService’ to ‘customerService’. And you can retrieve this component with name ‘customerService’. But if you use @Service annotation for the bean class you can provide a specific bean name by

@Service("AAA")
public class CustomerService{

and you can get the bean object by

CustomerService cust = (CustomerService)context.getBean("AAA");

Annotate other components with @Component, for example REST Resource classes.

@Component
public class AdressComp{
    .......
    ...//some code here    
}

@Component is a generic stereotype for any Spring managed component.

@Controller, @Service and @Repository are Specializations of @Component for specific use cases.

@Component in Spring

"Component Specialization"

The answers presented here are partially technically correct, but even though the response list is long and this will be at the bottom I thought it was worth putting an actually correct response in here too, just in case somebody stumbles upon it and learns something valuable from it. It's not that the rest of the answers are completely wrong, it's just that they aren't right. And, to stop the hordes of trolls, yes, I know that technically these annotations are effectively the same thing right now and mostly interchangeable even unto spring 5. Now, for the right answer:

These three annotations are completely different things and are not interchangeable. You can tell that because there are three of them rather than just one. They are not intended to be interchangeable, they're just implemented that way out of elegance and convenience.

Modern programming is invention, art, technique, and communication, in varying proportions. The communication bit is usually very important because code is usually read much more often than its written. As a programmer you're not only trying to solve the technical problem, you're also trying to communicate your intent to future programmers who read your code. These programmers may not share your native language, nor your social environment, and it is possible that they may be reading your code 50-years in the future (it's not as unlikely as you may think). It's difficult to communicate effectively that far into the future. Therefore, it is vital that we use the clearest, most efficient, correct, and communicative language available to us. That we chose our words carefully to have maximum impact and to be as clear as possible as to our intent.

For example, it is vital that @Repository is used when we're writing a repository, rather than @Component. The latter is a very poor choice of annotation for a repository because it does not indicate that we're looking at a repository. We can assume that a repository is also a spring-bean, but not that a component is a repository. With @Repository we are being clear and specific in our language. We are stating clearly that this is a repository. With @Component we are leaving it to the reader to decide what type of component they are reading, and they will have to read the whole class (and possibly a tree of subclasses and interfaces) to infer meaning. The class could then possibly be misinterpreted by a reader in the distant future as not being a repository, and we would have been partially responsible for this mistake because we, who knew full well that this is a repository, failed to be specific in our language and communicate effectively our intent.

I won't go into the other examples, but will state as clearly as I can: these annotations are completely different things and should be used appropriately, as per their intent. @Repository is for storage repositories and no other annotation is correct. @Service is for services and no other annotation is correct. @Component is for components that are neither repositories nor services, and to use either of these in its place would also be incorrect. It might compile, it might even run and pass your tests, but it would be wrong and I would think less of you (professionally) if you were to do this.

There are examples of this throughout spring (and programming in general). You must not use @Controller when writing a REST API, because @RestController is available. You must not use @RequestMapping when @GetMapping is a valid alternative. Etc. Etc. Etc. You must chose the most specific exact and correct language you can to communicate your intent to your readers, otherwise, you are introducing risks into your system, and risk has a cost.

Finally, I'd like to bring up a point of order concerning Object-Oriented systems. One of the fundamental rules is that implementations can vary but interfaces shouldn't. Assuming that these annotations are the same thing is a very slippery slope and completely against OO. Although they may be implemented in an interchangeable way now, there is no guarantee that they will be in the future. Further, even within the same team, an engineer may decide to hang some behaviour off one or more of these annotations using aspects, or a platform engineer may choose to replace the implementation of one of these for operational reasons. You just don't know, nor should you -- in OO you rely on the interface, not the implementation.

Good enough answers are here to explain the whats-the-difference-between-component-repository-service-annotations. I would like to share the difference between @Controller & @RestController

@Controller vs RestController

@RestController:

enter image description here

  • This annotation is a specialized version of @Controller which adds @Controller and @ResponseBody annotation automatically. so we do not have to add @ResponseBody to our mapping methods. That means @ResponseBody is default active.
  • If you use @RestController you cannot return a view (By using Viewresolver in Spring/Spring-Boot)
  • @RestController also converts the response to JSON/XML automatically as @ResponseBody makes the returned objects to something that could be in the body, e.g. JSON or XML

@Controller

enter image description here

  • @Controller is used to mark classes as Spring MVC Controller. This annotation is just a specialized version of @Component and it allows the controller classes to be auto-detected based on classpath scanning.
  • @Controller you can return a view in Spring web MVC.

More Detailed View

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.

Spring supports multiple types annotations such as @Component, @service, @Repository. All theses can be found under the org.springframework.stereotype package and @Bean can be found under org.springframework.context.annotation package.

When classes in our application are annotated with any of the above mentioned annotation then during project startup spring scan(using @ComponentScan) each class and inject the instance of the classes to the IOC container. Another thing the @ComponentScan would do is running the methods with @Bean on it and restore the return object to the Ioc Container as a bean.

Before we deep dive into ( @Component vs @service vs @Repository ) first it's better to understand the differences between @Bean and @Component

enter image description here


@Component vs @Repository vs @Service


In most typical applications, we have distinct layers like data access, presentation, service, business, etc. Additionally, in each layer we have various beans. To detect these beans automatically, Spring uses classpath scanning annotations.Then it registers each bean in the ApplicationContext.

Here's a short overview of a few of these annotations:

  • @Component is a generic stereotype for any Spring-managed component.
  • @Service annotates classes at the service layer.
  • @Repository annotates classes at the persistence layer, which will act as a database repository.

@Component Annotation

@Component is a class level annotation.We can use @Component across the application to mark the beans as Spring's managed components. Spring will only pick up and register beans with @Component, and doesn't look for @Service and @Repository in general.

They are registered in ApplicationContext because they are annotated with @Component

As stated, @Component is the parent of all stereotype annotations. When Spring performs a component scan, it only looks for classes marked with @Component annotations.

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Indexed
public @interface Component {
    String value() default "";
}

We can use this annotation on all the classes and it won’t cause any difference.

@Service Annotation

We mark beans with @Service to indicate that they're holding the business logic. Besides being used in the service layer, there isn't any other special use for this annotation.

The @Service is child of component and used to denote classes from the service layer of the application.

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Service {
   @AliasFor(
       annotation = Component.class
   )
   String value() default "";
}

@Repository Annotation

@Repository’s job is to catch persistence-specific exceptions and re-throw them as one of Spring’s unified unchecked exceptions.

For this, Spring provides PersistenceExceptionTranslationPostProcessor, which we are required to add in our application context (already included if we're using Spring Boot):

<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>

This bean post processor adds an advisor to any bean that’s annotated with @Repository.

Similarly, @Repository is also a child of component annotation and used on the classes that belong to persistence data access layer and serves as a data repository.

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Repository {
    @AliasFor(
        annotation = Component.class
    )
    String value() default "";
}

Summary

@Service and @Repository are special cases of @Component. They are technically the same, but we use them for the different purposes.It's always a good idea to choose the annotation based on their layer conventions.

@Component acts as @Bean annotation in configuration class , register bean in spring context. Also it is parent for @Service, @Repository and @Controller annotation.

@Service, extends @Component annotation and has only naming difference.

@Repository - extends @Component annotation and translate all database exceptions into DataAccessException.

@Controller - acts as controller in MVC pattern. The dispatcher will scan such annotated classes for mapped methods, detecting @RequestMapping annotations.

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 spring framework provides some special type of annotations,called stereotype annotations. These are following:-

@RestController- Declare at controller level.
@Controller – Declare at controller level.
@Component – Declare at Bean/entity level.
@Repository – Declare at DAO level.
@Service – Declare at BO level.

above declared annotations are special because when we add <context:component-scan> into xxx-servlet.xml file ,spring will automatically create the object of those classes which are annotated with above annotation during context creation/loading phase.

@Component, @ Repository, @ Service, @Controller:

@Component is a generic stereotype for the components managed by Spring @Repository, @Service, and @Controller are @Component specializations for more specific uses:

  • @Repository for persistence
  • @Service for services and transactions
  • @Controller for MVC controllers

Why use @Repository, @Service, @Controller over @Component? We can mark our component classes with @Component, but if instead we use the alternative that adapts to the expected functionality. Our classes are better suited to the functionality expected in each particular case.

A class annotated with @Repository has a better translation and readable error handling with org.springframework.dao.DataAccessException. Ideal for implementing components that access data (DataAccessObject or DAO).

An annotated class with @Controller plays a controller role in a Spring Web MVC application

An annotated class with @Service plays a role in business logic services, example Facade pattern for DAO Manager (Facade) and transaction handling

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;

    // Your logic
}

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.

@Component
@Controller
@Repository
@Service
@RestController

These are all StereoType annotations.this are usefull for the making our classes as spring beans in ioc container,

Related