Introduction: Why Does Spring Have Three Annotations for the Same Thing?
\n\nEveryone who starts working with Spring eventually asks: "Why are three different annotations needed — @Component, @Repository, and @Service — if they all simply register a bean in the context?"
This question is so popular that on Stack Overflow it has gathered thousands of views and dozens of answers. And this is no coincidence. At first glance, the annotations really do the same thing. But the devil, as always, is in the details.
\n\nIn this article, we won't just list the differences. We will break down the philosophy of Spring, look under the hood of the container, and show how proper use of annotations can save your project from hidden bugs. Let's go!
\n\nQuick Primer: What Are Stereotype Annotations?
\n\nAll three annotations belong to the so-called stereotype annotations. They tell Spring that the class is a managed component (bean) and should be automatically discovered during classpath scanning.
\n\nThe base annotation is @Component. It is the foundation. @Repository, @Service, and @Controller are specialized forms of @Component that add additional semantics and behavior.
@Target(ElementType.TYPE)\n@Retention(RetentionPolicy.RUNTIME)\n@Documented\n@Component // Here is the key point!\npublic @interface Service {\n // ...\n}\n\nAs you can see, @Service itself is annotated with @Component. This means Spring will process it exactly the same way as a regular @Component. But why complicate things then?
@Component — The Universal Soldier
\n\n@Component is the most general annotation. Use it when your class does not fit into any of the more specific categories.
Typical examples:
\n- \n
- Helper utilities \n
- Configuration objects (not to be confused with
@Configuration) \n - Any classes that should be beans but are not services, repositories, or controllers \n
import org.springframework.stereotype.Component;\n\n@Component\npublic class EmailValidator {\n\n public boolean isValid(String email) {\n return email != null && email.contains("@");\n }\n}\n\nNote: EmailValidator does not perform business logic (it's not a @Service) and does not work with a database (it's not a @Repository). Therefore, @Component is the ideal choice.
@Repository — The Guardian of Data
\n\n@Repository is the first specialized annotation that adds real functionality. In addition to registering the bean, it performs two important tasks:
- \n
- Exception translation for data access. Spring automatically wraps exceptions from DAO (Data Access Object) into
DataAccessException— Spring's exception hierarchy. \n - Improved code readability. Any developer, seeing
@Repository, immediately understands: "Aha, this is working with a database." \n
import org.springframework.stereotype.Repository;\nimport org.springframework.data.jpa.repository.JpaRepository;\n\n@Repository\npublic interface UserRepository extends JpaRepository<User, Long> {\n\n User findByEmail(String email);\n}\n\nImportant: If you are using Spring Data JPA and extending JpaRepository, Spring will create the proxy bean itself. The explicit @Repository annotation is not required, but it is recommended to clearly indicate its purpose.
The main "feature" of @Repository is the AOP interceptor (PersistenceExceptionTranslationPostProcessor)
Blogs
Book Recommendations
Read also
Kotlin List to Map: Guide to Conversion and Code Acceleration
CI/CD for C# Projects: GitHub Actions at an Advanced Level
Java Developer Salaries in Russia: Market Overview for Advanced Level
Creating CLI Utilities in Java: From Idea to Ready Tool
== and === in Swift: What's the Difference and What's Under the Hood