Introdução: Por que três anotações no Spring para a mesma coisa?
\n\nTodo mundo que começou a trabalhar com Spring, mais cedo ou mais tarde, se perguntou: "Por que são necessárias três anotações diferentes — @Component, @Repository e @Service — se todas apenas registram um bean no contexto?".
Essa pergunta é tão popular que no Stack Overflow ela acumulou milhares de visualizações e dezenas de respostas. E não é por acaso. À primeira vista, as anotações realmente fazem a mesma coisa. Mas o diabo, como sempre, está nos detalhes.
\n\nNeste artigo, não vamos apenas listar as diferenças. Vamos analisar a filosofia do Spring, olhar sob o capô do contêiner e mostrar como o uso correto das anotações pode salvar seu projeto de bugs ocultos. Vamos lá!
\n\nBreve introdução: O que são anotações estereotipadas?
\n\nTodas as três anotações pertencem às chamadas anotações estereotipadas (stereotype annotations). Elas informam ao Spring que a classe é um componente gerenciado (bean) e deve ser automaticamente descoberta durante a varredura do classpath.
\n\nA anotação base é @Component. Ela é o fundamento. @Repository, @Service e @Controller são formas especializadas de @Component, que adicionam semântica e comportamento extras.
@Target(ElementType.TYPE)\n@Retention(RetentionPolicy.RUNTIME)\n@Documented\n@Component // Aqui está o ponto chave!\npublic @interface Service {\n // ...\n}\n\nComo você pode ver, o próprio @Service é anotado com @Component. Isso significa que o Spring o processará exatamente da mesma forma que um @Component comum. Mas então por que complicar?
@Component — o soldado universal
\n\n@Component é a anotação mais geral. Use-a quando sua classe não se encaixa em nenhuma das categorias mais específicas.
Exemplos típicos:
\n- \n
- Utilitários auxiliares \n
- Objetos de configuração (não confundir com
@Configuration) \n - Quaisquer classes que devem ser beans, mas não são serviços, repositórios ou controladores \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\nObserve: EmailValidator não executa lógica de negócios (não é um @Service) e não trabalha com banco de dados (não é um @Repository). Portanto, @Component é a escolha ideal.
@Repository — o guardião dos dados
\n\n@Repository é a primeira anotação especializada que adiciona funcionalidade real. Além de registrar o bean, ela executa duas tarefas importantes:
- \n
- Captura de exceções de acesso a dados. O Spring automaticamente encapsula as exceções do DAO (Data Access Object) em
DataAccessException— a hierarquia de exceções do Spring. \n - Melhora a legibilidade do código. Qualquer desenvolvedor, ao ver
@Repository, entende imediatamente: "Ah, aqui é onde se trabalha com o banco de dados". \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: Se você usa Spring Data JPA e herda de JpaRepository, o Spring criará o bean proxy automaticamente. A anotação explícita @Repository não é obrigatória, mas é recomendada para indicar claramente o propósito.
A principal "sacada" do @Repository é o interceptor AOP (PersistenceExceptionTranslationPostProcessor)
Blogs
Book Recommendations
Leia também
GraphQL vs REST em C#: o que escolher para sua API em 2024
Lendo arquivo linha por linha em Go: melhores práticas 2025
Como escrever uma API REST em Go em 30 minutos: guia passo a passo
Internacionalização de aplicações Go: de $ a € sem dor de cabeça
Programação Assíncrona em C#: guia completo com exemplos