As many of the answers already state what these annotations are used for, we'll here focus on some minor differences among them.
> First the **Similarity**
>
> First point worth highlighting again is that **with respect to scan-auto-detection and dependency injection for BeanDefinition** all these annotations (viz., @Component, @Service,
> @Repository, @Controller) are the same. **We can use one in place
> of another and can still get our way around.**
----------
## Differences between @Component, @Repository, @Controller and @Service ##
> **@Component**
This is a general-purpose stereotype annotation indicating that the class is a spring component.
***What’s special about @Component***
`<context:component-scan>` 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`.
Special type annotations are also scanned, because they themselves are annotated with `@Component` annotation, which means they are also `@Component`s. If we define our own custom annotation and annotate it with `@Component`, it will also get scanned with `<context:component-scan>`
----------
> **@Repository**
This is to indicate that the class defines a data repository.
***What’s special about @Repository?***
In addition to pointing out, that this is an *Annotation based Configuration*, `@Repository`’s job is to catch platform specific exceptions and re-throw them as one of Spring’s unified unchecked exception. For this, we’re provided with `PersistenceExceptionTranslationPostProcessor`, that we are required to add in our Spring’s application context like this:
<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>
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 re-thrown as one of Spring’s unchecked data access exceptions.
----------
> **@Controller**
The `@Controller` annotation indicates that a particular class serves the role of a controller. The `@Controller` annotation acts as a stereotype for the annotated class, indicating its role.
***What’s special about @Controller?***
We cannot switch this annotation with any other like `@Service` or `@Repository`, even though they look same.
The dispatcher scans the classes annotated with `@Controller` and detects methods annotated with `@RequestMapping` annotations within them. We can use `@RequestMapping` on/in only those methods whose classes are annotated with `@Controller` and it will **NOT** work with `@Component`, `@Service`, `@Repository` etc...
<sub>_Note: If a class is already registered as a bean through any alternate method, like through `@Bean` or through `@Component`, `@Service` etc... annotations, then `@RequestMapping` can be picked if the class is also annotated with `@RequestMapping` annotation. But that's a different scenario._</sub>
----------
> **@Service**
`@Service` beans hold the business logic and call methods in the repository layer.
***What’s special about @Service?***
Apart from the fact that it's used to indicate, that it's holding the business logic, there’s nothing else noticeable in this annotation; but who knows, Spring may add some additional exceptional in future.
----------
> ***What else?***
Similar to above, in the future Spring may add special functionalities for `@Service`, `@Controller` and `@Repository` based on their layering conventions. Hence, it's always a good idea to respect the convention and use it in line with layers.