Question
Spring @Component vs @Repository vs @Service: What's the Difference?
Question
In Spring, can @Component, @Repository, and @Service be used interchangeably, or do they provide specific functionality beyond simply marking a class?
For example, if a service class is annotated with @Service and I change it to @Component, will it still behave the same way?
Does the chosen annotation affect the behavior and functionality of the class, or is it mainly used for organization and readability?
Short Answer
By the end of this page, you will understand how Spring stereotype annotations work, what @Component, @Service, and @Repository have in common, and where they differ. You will also learn when they are interchangeable, when they are not, and why using the most specific annotation improves code clarity and framework integration.
Concept
Spring uses stereotype annotations to mark classes as beans that should be detected during component scanning and managed by the Spring container.
The three annotations in this question are closely related:
@Component
@Service
@Repository
The core idea
@Service and @Repository are specialized forms of @Component.
That means:
- A class annotated with any of them can usually be discovered by component scanning.
- Spring can create an object for that class and manage its lifecycle as a bean.
- You can inject that bean into other classes using dependency injection.
What they have in common
All three typically:
- Register the class as a Spring bean
- Allow dependency injection
- Participate in component scanning
- Represent application-layer classes managed by Spring
What makes them different
The difference is mostly about meaning and framework behavior.
@Component
This is the most general stereotype. It says:
- "This class is a Spring-managed component."
Use it when the class does not clearly belong to a more specific role.
@Service
This is a semantic specialization of @Component. It says:
- "This class contains business logic."
In many Spring applications, @Service behaves the same as @Component at runtime. The main benefit is clearer design and better communication to other developers.
@Repository
This is also a specialization of @Component, but it has an important extra purpose:
- "This class handles database access or persistence."
@Repository can trigger exception translation in Spring. That means low-level persistence exceptions may be converted into Spring's consistent DataAccessException hierarchy.
This is the main practical behavior difference among these annotations.
Why this matters
In real projects, these annotations help define architecture clearly:
@Controlleror@RestControllerfor web layer@Servicefor business layer@Repositoryfor data access layer@Componentfor general-purpose helper classes
Even when @Service and @Component behave similarly today, using the specific annotation makes your codebase easier to understand, maintain, and extend.
Mental Model
Think of @Component as a general label that says, "Put this object on Spring's staff list."
Then think of @Service and @Repository as job titles:
@Component= employee@Service= business manager@Repository= database specialist
All of them are employees, so they can enter the building and do work. But the job title tells everyone what role they play.
In one case, the job title can also change behavior:
@Repositorynot only says "database specialist"- it also allows Spring to treat certain database errors in a special way
So the labels are not only decorative. They are partly descriptive, and in some cases, they affect framework behavior too.
Syntax and Examples
Basic syntax
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import org.springframework.stereotype.Repository;
@Component
public class EmailFormatter {
}
@Service
public class OrderService {
}
@Repository
public class OrderRepository {
}
Each of these classes can be discovered by component scanning and registered as a Spring bean.
Example with dependency injection
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;
@Repository
public class UserRepository {
public String findUsernameById(long id) {
return "alice";
}
}
@Service
public class UserService {
private final UserRepository userRepository;
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
public String getDisplayName(long id) {
return userRepository.findUsernameById(id).toUpperCase();
}
}
What this shows
UserRepositoryis a Spring bean because it is marked with@RepositoryUserServiceis a Spring bean because it is marked with@Service- Spring injects
UserRepositoryintoUserService - The service layer uses the repository layer to fetch data and apply business logic
If @Service becomes @Component
import org.springframework.stereotype.Component;
@Component
public class UserService {
private final UserRepository userRepository;
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
public String getDisplayName(long id) {
return userRepository.findUsernameById(id).toUpperCase();
}
}
This will usually still work the same way as long as component scanning includes the class.
The main change is that the class no longer explicitly communicates that it belongs to the service layer.
Important exception: @Repository
Changing a repository class from @Repository to @Component may remove repository-specific behavior such as persistence exception translation in some setups.
So:
@Service↔@Component: often functionally similar@Repository↔@Component: not always equivalent
Step by Step Execution
Consider this example:
@Repository
public class ProductRepository {
public String findById(int id) {
return "Laptop";
}
}
@Service
public class ProductService {
private final ProductRepository productRepository;
public ProductService(ProductRepository productRepository) {
this.productRepository = productRepository;
}
public String getProductLabel(int id) {
String product = productRepository.findById(id);
return "Product: " + product;
}
}
Step by step
1. Spring scans the package
Spring looks for classes annotated with stereotypes such as:
@Component@Service@Repository
It finds both ProductRepository and ProductService.
2. Spring creates beans
Spring creates managed objects for both classes and stores them in the application context.
3. Spring resolves dependencies
ProductService needs a ProductRepository in its constructor.
Spring sees that a ProductRepository bean exists, so it injects it automatically.
4. Your code calls the service
If some controller or other bean calls:
productService.getProductLabel(10);
then this method runs.
5. The service calls the repository
Inside getProductLabel, this line runs:
String product = productRepository.findById(id);
The repository returns:
"Laptop"
6. The service adds business logic
The service returns:
"Product: Laptop"
What if @Service becomes @Component?
Spring would still:
- detect the class
- create the bean
- inject the dependency
So execution would usually be unchanged.
What if @Repository becomes @Component?
The bean would still likely be created and injected, but you may lose repository-specific exception handling behavior. That is why repository classes should normally use @Repository.
Real World Use Cases
Where @Component is used
Use @Component for general-purpose classes that do not clearly belong to the service or persistence layer.
Examples:
- utility classes managed by Spring
- custom validators
- token generators
- file parsers
- scheduled task helpers
@Component
public class SlugGenerator {
public String toSlug(String text) {
return text.toLowerCase().replace(" ", "-");
}
}
Where @Service is used
Use @Service for business rules and application workflows.
Examples:
- order processing
- payment logic
- account registration rules
- email sending coordination
- report generation
@Service
public class PaymentService {
public boolean processPayment(double amount) {
return amount > 0;
}
}
Where @Repository is used
Use @Repository for database access.
Examples:
- JPA or JDBC data access classes
- custom query classes
- persistence adapters
- DAO-style classes
@Repository
public class CustomerRepository {
public void save(Customer customer) {
// database logic
}
}
In layered applications
A common flow looks like this:
- controller receives request
- service applies business rules
- repository reads or writes data
This separation makes applications easier to test and maintain.
Real Codebase Usage
In real projects, developers rarely choose these annotations randomly. They use them to communicate architecture and to support framework conventions.
Common pattern: layered architecture
@RestController
public class OrderController {
private final OrderService orderService;
public OrderController(OrderService orderService) {
this.orderService = orderService;
}
}
@Service
public class OrderService {
private final OrderRepository orderRepository;
public OrderService(OrderRepository orderRepository) {
this.orderRepository = orderRepository;
}
}
@Repository
public class OrderRepository {
}
This tells readers immediately what each class is responsible for.
Guard clauses and validation in services
Services often contain checks before calling repositories:
@Service
public class AccountService {
public void register(String email) {
if (email == null || email.isBlank()) {
throw new IllegalArgumentException("Email is required");
}
// business logic continues
}
}
Error handling in repositories
Repositories isolate persistence logic so database-related failures stay in one place.
@Repository
public class JdbcInventoryRepository {
public int countItems() {
// query database
return 0;
}
}
Why teams prefer specific stereotypes
Using the most specific stereotype helps with:
- code readability
- architecture reviews
- onboarding new developers
- consistent package structure
- framework integrations such as exception translation
Practical guideline
- Use
@Repositoryfor persistence classes - Use
@Servicefor business logic classes - Use
@Componentfor everything else that should be a Spring bean
Common Mistakes
1. Using @Component everywhere
This works technically in many cases, but it hides the role of each class.
Less clear
@Component
public class InvoiceService {
}
@Component
public class InvoiceRepository {
}
Better
@Service
public class InvoiceService {
}
@Repository
public class InvoiceRepository {
}
2. Thinking @Service adds major built-in business logic features
Beginners sometimes assume @Service automatically changes how methods run.
Usually, it does not add special runtime behavior by itself. It mainly provides semantic meaning as a specialized @Component.
3. Replacing @Repository with @Component for database classes
This can be a real mistake because repository-specific exception translation may no longer apply.
Risky
@Component
public class UserRepository {
// database code
}
Better
@Repository
public class UserRepository {
// database code
}
4. Confusing stereotypes with bean scope
These annotations do not decide whether a bean is singleton, prototype, request-scoped, or session-scoped.
Bean scope is controlled separately, for example with @Scope.
5. Forgetting component scanning
Even if a class has @Service or @Repository, Spring must still scan the package.
If the package is outside the scan path, the bean will not be created.
6. Putting business logic in repositories
Repositories should focus on persistence. Services should contain business rules.
Not ideal
@Repository
public class DiscountRepository {
public double calculateDiscount(Customer customer) {
return 0.15;
}
}
Better
@Service
public class DiscountService {
public double calculateDiscount(Customer customer) {
return 0.15;
}
}
Comparisons
Quick comparison
| Annotation | Is it a Spring bean stereotype? | Main purpose | Extra behavior | Best use |
|---|---|---|---|---|
@Component | Yes | General-purpose Spring-managed class | Usually none specific | Helpers, utilities, generic components |
@Service | Yes | Business logic layer | Mostly semantic in common usage | Services, workflows, application rules |
@Repository | Yes | Persistence/data access layer | Exception translation for persistence errors | DAO, JPA, JDBC, database access |
@Service vs @Component
| Point | @Service | @Component |
|---|---|---|
| Meaning | Business logic | General bean |
| Bean registration | Yes | Yes |
| Common runtime difference | Usually none | Usually none |
| Best choice for service classes | Yes | Possible, but less clear |
@Repository vs @Component
| Point | @Repository | @Component |
|---|---|---|
| Meaning | Data access | General bean |
| Bean registration | Yes | Yes |
| Exception translation | Often yes | Usually no |
| Best choice for DB classes | Yes | Usually no |
Are they interchangeable?
@Serviceand@Componentare often interchangeable in behavior, but not equally expressive.@Repositoryand@Componentare not always interchangeable because@Repositorymay enable extra persistence-related behavior.
Cheat Sheet
Quick rules
@Component= general Spring-managed bean@Service= business logic bean@Repository= data access bean@Serviceand@Repositoryare specialized versions of@Component
What all three do
- make the class eligible for component scanning
- register it as a Spring bean
- allow dependency injection
Important difference
@Repositorycan enable persistence exception translation@Serviceis usually mainly semantic and architectural
Good defaults
@Component // generic helper or utility
@Service // business logic
@Repository // database access
Typical layered structure
@RestController
class UserController {}
@Service
class UserService {}
@Repository
class UserRepository {}
Common interview-style answer
@Service and @Repository are stereotype annotations built on top of @Component. All can create Spring beans, but @Repository may add exception translation, while @Service mainly adds semantic meaning.
Edge case to remember
If you change a class from @Service to @Component, it will usually still work.
If you change a class from @Repository to @Component, it may still work as a bean, but some repository-specific behavior may be lost.
FAQ
Can @Component, @Service, and @Repository all create Spring beans?
Yes. All three can mark a class for component scanning so Spring can create and manage it as a bean.
Is @Service just a special kind of @Component?
Yes. @Service is a specialization of @Component, mainly used to indicate business logic.
Does changing @Service to @Component usually break anything?
Usually no, as long as component scanning still finds the class. The bean will typically behave the same way.
Why should I use @Repository instead of @Component for database classes?
Because @Repository clearly marks persistence code and can enable Spring's persistence exception translation.
Does @Service provide extra runtime features by default?
In common usage, not much. Its biggest value is semantic clarity and better architecture communication.
Are these annotations required for dependency injection?
A class usually needs to be registered as a bean somehow. These annotations are one common way to do that through component scanning.
What happens if Spring does not scan the package?
The class will not be registered as a bean, even if it has @Component, @Service, or @Repository.
Should I always use the most specific stereotype?
Yes, in most cases. It makes the code easier to understand and can enable framework-specific behavior where relevant.
Mini Project
Description
Build a small layered Spring example with a utility component, a service, and a repository. This project helps you see where each stereotype belongs and how the classes work together in a realistic structure.
Goal
Create a simple user lookup flow where a service calls a repository and also uses a general-purpose component.
Requirements
- Create one class annotated with
@Componentfor formatting usernames - Create one class annotated with
@Repositorythat returns a hardcoded username - Create one class annotated with
@Servicethat uses both classes - Add one runner or test method that calls the service and prints the result
Keep learning
Related questions
Add External JAR Files to an IntelliJ IDEA Java Project
Learn how to add external JAR dependencies to an IntelliJ IDEA Java project using module libraries, and when to use Maven or Gradle instead.
Avoiding Java Code in JSP with JSP 2: EL and JSTL Explained
Learn how to avoid Java scriptlets in JSP 2 using Expression Language and JSTL, with examples, best practices, and common mistakes.
Call a Method After a Delay in Android Java
Learn how to run Java code after a delay in Android using Handler.postDelayed, manage the main thread, and cancel callbacks safely.