20. Inversão de Controle (IoC) e Injeção de Dependência (DI)
Antes de mergulharmos no Spring Boot, precisamos entender dois conceitos fundamentais que sustentam todo o framework: Inversão de Controle e Injeção de Dependência. Eles são a chave para criar sistemas desacoplados e fáceis de testar.
O Problema: Acoplamento Forte
Imagine que você está construindo um carro. No modo tradicional (sem IoC), a própria classe Carro cria o seu Motor.
public class Carro {
private Motor motor;
public Carro() {
// O Carro TEM O CONTROLE sobre a criação do Motor.
// Ele está fortemente acoplado a um tipo específico de Motor.
this.motor = new MotorV8();
}
}
Se quisermos mudar o motor para um MotorEletrico, teremos que alterar o código da classe Carro. Isso é acoplamento forte e dificulta a manutenção e os testes.
A Solução parte 1: Injeção de Dependência (DI)
Em vez de a classe criar suas próprias dependências, nós as injetamos (passamos) de fora, geralmente através do construtor.
public class Carro {
private Motor motor;
// O Motor é passado para o Carro.
// O Carro não sabe COMO o motor foi criado, ele apenas o USA.
public Carro(Motor motor) {
this.motor = motor;
}
}
Agora o Carro pode receber qualquer tipo de Motor (V8, Elétrico, Flex), desde que implementem a interface Motor. Isso é Injeção de Dependência.
A Solução parte 2: Inversão de Controle (IoC)
Mas quem cria o Motor e o passa para o Carro? É aí que entra o Container de IoC (como o Spring).
Em um sistema tradicional, o fluxo de controle é do seu código chamando bibliotecas. Com IoC, o framework chama o seu código. O controle sobre o ciclo de vida dos objetos é invertido.
No Spring, nós apenas dizemos: “Spring, eu preciso de um Carro e de um Motor. Crie-os e conecte-os para mim!”. Nós fazemos isso usando anotações como @Component e @Autowired.
Resumo Didático
- Sem IoC/DI: Você vai ao mercado, compra as peças e monta o carro você mesmo.
- Com IoC/DI: Você liga para uma fábrica (Spring), diz o que quer, e eles te entregam o carro montado e pronto para uso.
Esses conceitos permitem que o Spring gerencie as conexões entre Controllers, Services e Repositories de forma automática, como veremos nos projetos práticos.