Introducción: ¿Por qué Spring tiene tres anotaciones para lo mismo?
\n\nCualquiera que haya empezado a trabajar con Spring, tarde o temprano se ha preguntado: "¿Por qué se necesitan tres anotaciones diferentes — @Component, @Repository y @Service — si todas simplemente registran un bean en el contexto?".
Esta pregunta es tan popular que en Stack Overflow ha acumulado miles de visitas y decenas de respuestas. Y no es casualidad. A primera vista, las anotaciones realmente hacen lo mismo. Pero el diablo, como siempre, está en los detalles.
\n\nEn este artículo no solo enumeraremos las diferencias. Analizaremos la filosofía de Spring, exploraremos el interior del contenedor y mostraremos cómo el uso correcto de las anotaciones puede salvar tu proyecto de errores ocultos. ¡Allá vamos!
\n\nBreve introducción: ¿Qué son las anotaciones estereotipo?
\n\nLas tres anotaciones pertenecen a las llamadas anotaciones estereotipo (stereotype annotations). Le indican a Spring que la clase es un componente gestionado (bean) y debe ser detectada automáticamente durante el escaneo del classpath.
\n\nLa anotación base es @Component. Ella es el fundamento. @Repository, @Service y @Controller son formas especializadas de @Component que añaden semántica y comportamiento adicionales.
@Target(ElementType.TYPE)\n@Retention(RetentionPolicy.RUNTIME)\n@Documented\n@Component // ¡Aquí está el punto clave!\npublic @interface Service {\n // ...\n}\n\nComo se puede ver, @Service está a su vez anotada con @Component. Esto significa que Spring la procesará exactamente igual que un @Component normal. Pero entonces, ¿por qué complicarlo?
@Component — el soldado universal
\n\n@Component es la anotación más general. Úsala cuando tu clase no encaje en ninguna de las categorías más específicas.
Ejemplos típicos:
\n- \n
- Utilidades auxiliares \n
- Objetos de configuración (no confundir con
@Configuration) \n - Cualquier clase que deba ser un bean, pero no sea un servicio, repositorio o controlador \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\nObserva: EmailValidator no ejecuta lógica de negocio (no es un @Service) ni trabaja con la base de datos (no es un @Repository). Por lo tanto, @Component es la elección ideal.
@Repository — el guardián de los datos
\n\n@Repository es la primera anotación especializada que agrega funcionalidad real. Además de registrar el bean, realiza dos tareas importantes:
- \n
- Intercepción de excepciones de acceso a datos. Spring envuelve automáticamente las excepciones de DAO (Data Access Object) en
DataAccessException— la jerarquía de excepciones de Spring. \n - Mejora de la legibilidad del código. Cualquier desarrollador, al ver
@Repository, entiende de inmediato: "Ajá, aquí se trabaja con la base de datos". \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\nImportante: Si usas Spring Data JPA y heredas de JpaRepository, Spring creará el bean proxy por sí mismo. La anotación explícita @Repository no es obligatoria, pero se recomienda para indicar claramente su propósito.
La principal "característica" de @Repository es el interceptor AOP (PersistenceExceptionTranslationPostProcessor)
Blogs
Book Recommendations
Leer también
Kotlin y PostgreSQL: escribiendo un backend más rápido de lo que pensabas
Despliegue de una aplicación Rust en VPS: guía paso a paso
Asistente de IA en PHP: cómo generar código, no buscar errores
Concurrencia y multihilo en Go: nivel avanzado
WebAssembly y PHP: ¿qué son y para qué sirven? Tándem inesperado para la web