Anotações Spring: @Component, @Repository, @Service — qual a diferença?

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Introdução: Por que três anotações no Spring para a mesma coisa?

\n\n

Todo 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?".

\n\n

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\n

Neste 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\n

Breve introdução: O que são anotações estereotipadas?

\n\n

Todas 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\n

A anotação base é @Component. Ela é o fundamento. @Repository, @Service e @Controller são formas especializadas de @Component, que adicionam semântica e comportamento extras.

\n\n
@Target(ElementType.TYPE)\n@Retention(RetentionPolicy.RUNTIME)\n@Documented\n@Component // Aqui está o ponto chave!\npublic @interface Service {\n    // ...\n}
\n\n

Como 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?

\n\n

@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.

\n\n

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
\n\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\n

Observe: 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.

\n\n

@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\n
    \n
  1. 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.
  2. \n
  3. Melhora a legibilidade do código. Qualquer desenvolvedor, ao ver @Repository, entende imediatamente: "Ah, aqui é onde se trabalha com o banco de dados".
  4. \n
\n\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\n

Importante: 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.

\n\n

A principal "sacada" do @Repository é o interceptor AOP (PersistenceExceptionTranslationPostProcessor)

Blogs

Book Recommendations