Injeção de Dependência em Java: para iniciantes — guia completo

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

O que é Injeção de Dependência em Java e para que serve?



Imagine que você está construindo uma casa. Você precisa de tijolos, cimento e ferramentas. Se você mesmo tiver que extrair a argila, queimar os tijolos e preparar o cimento a cada vez, a construção levaria uma eternidade. É muito mais fácil quando os materiais já estão prontos e entregues no canteiro de obras. É exatamente assim que funciona a Injeção de Dependência (DI) em Java — é um padrão de projeto no qual um objeto recebe dependências prontas de fora, em vez de criá-las por conta própria.



Em palavras simples: injeção de dependência (Dependency Injection) é quando um objeto passa para outro objeto todas as dependências necessárias. Em vez de a classe criar suas próprias dependências, ela as recebe através de um construtor, setter ou interface.



Por que a Injeção de Dependência é tão importante?



  • Redução do acoplamento do código: As classes deixam de depender rigidamente de implementações específicas.
  • Facilitação dos testes: Você pode substituir facilmente objetos reais por mocks (objetos simulados) em testes unitários.
  • Aumento da reutilização: A mesma classe pode ser usada em contextos diferentes.
  • Melhora da legibilidade: O código fica mais claro e as dependências se tornam explícitas.


O problema sem Injeção de Dependência: antipadrão "Acoplamento Rígido"



Vamos ver um exemplo típico de código sem usar DI. Suponha que temos uma classe EmailService, que envia e-mails, e uma classe NotificationService, que usa o EmailService.



// Classe sem DI — exemplo ruimpublic class EmailService {    public void sendEmail(String message) {        System.out.println("Enviando email: " + message);    }}

public class NotificationService { private EmailService emailService;

public NotificationService() { // Problema: criando a dependência diretamente dentro da classe this.emailService = new EmailService(); }

public void sendNotification(String message) { emailService.sendEmail(message); }}


Qual é o problema desse código?



  • Acoplamento rígido: NotificationService está firmemente ligado ao EmailService. Se você quiser enviar SMS em vez de e-mail, terá que reescrever a classe.
  • Dificuldade de teste: Você não pode substituir o EmailService por um stub de teste (mock).
  • Violação do princípio da responsabilidade única: A classe NotificationService é responsável não apenas pelas notificações, mas também pela criação do serviço de envio.


Como funciona a Injeção de Dependência: três formas de injeção



Em Java, existem três maneiras principais de implementar a injeção de dependências. Vamos analisar cada uma com exemplos de código.



1. Injeção via construtor (Constructor Injection)



Esta é a forma mais comum e recomendada. As dependências são passadas através dos parâmetros do construtor.



// Interface para flexibilidadepublic interface MessageService {    void sendMessage(String message);}

// Implementação para emailpublic class EmailService implements MessageService { @Override public void sendMessage(String message) { System.out.println("Email enviado: " + message); }}

// Implementação para SMSpublic class SmsService implements MessageService { @Override public void sendMessage(String message) { System.out.println("SMS enviado: " + message); }}

// Classe com DI via construtorpublic class NotificationService { private final MessageService messageService;

// Injeção de dependência via construtor public NotificationService(MessageService messageService) { this.messageService = messageSe

Blogs

Book Recommendations