15‐Defining Dependency Injection - JulianeMaran32/Java-with-Spring-Boot GitHub Wiki
A Injeção de Dependência (Dependency Injection) é uma forma de aplicar o Princípio da Inversão de Dependência. Isso significa que um objeto (cliente) não é responsável por criar suas dependências. Em vez disso, outro objeto (geralmente o Spring) fornece o que ele precisa.
Imagine que você quer comprar um carro. Você vai até uma fábrica e diz: “Me dê um carro”. A fábrica monta o carro para você, juntando as peças (motor, portas, volante, etc.) e entrega o carro pronto.
A ideia é a mesma com injeção de dependência: ao invés de criar as partes do objeto manualmente, você apenas pede, e o Spring monta tudo pra você.
sequenceDiagram
participant Cliente
participant Fabrica
participant Carro
participant Pecas
Cliente->>Fabrica: Me dê um Carro
Fabrica->>Pecas: Montar com Motor, Portas, etc.
Pecas-->>Fabrica: Peças entregues
Fabrica-->>Cliente: Carro pronto
O Contêiner do Spring funciona como uma fábrica de objetos. Ele é responsável por:
- Criar e gerenciar objetos (Inversão de Controle - IoC).
- Injetar dependências nos objetos (Injeção de Dependência - DI).
graph LR
A[My App] -->|pede um objeto 'Coach'| B[Spring: Object Factory]
B --> C[Configuração]
C --> D[CricketCoach]
C --> E[BaseballCoach]
C --> F[HockeyCoach]
B -->|retorna objeto 'Coach'| A
- Criamos uma interface
Coach
, que oferece treinos diários. - O controlador
DemoController
quer usar umCoach
. -
Coach
é uma dependência doDemoController
. - Precisamos injetar essa dependência com Spring.
O Spring oferece diferentes formas de injetar dependências. As mais recomendadas são:
- Injeção via Construtor
- Injeção via Setter
- Construtor: Use quando a dependência é obrigatória. É o método mais recomendado.
- Setter: Use quando a dependência for opcional. Permite lógica padrão caso a dependência não seja fornecida.
O Spring pode autoconfigurar as dependências automaticamente:
- Ele procura uma classe que combine com o tipo da dependência (interface ou classe).
- Se encontrar, ele injeta automaticamente.
- Temos a interface
Coach
. - Temos uma classe
CricketCoach
com@Component
. - O Spring detecta isso e injeta automaticamente onde for necessário.
sequenceDiagram
participant Browser
participant DemoController
participant Coach
Browser->>DemoController: GET /dailyworkout
DemoController->>Coach: getDailyWorkout()
Coach-->>DemoController: "Pratique boliche rápido por 15 minutos"
DemoController-->>Browser: "Pratique boliche rápido por 15 minutos"
1. Definir a interface e a classe de dependência
Coach.java
public interface Coach {
String getDailyWorkout();
}
CricketCoach.java
@Component
public class CricketCoach implements Coach {
public String getDailyWorkout() {
return "Pratique boliche rápido por 15 minutos";
}
}
@Component
: marca a classe como um Bean do Spring, ou seja, um objeto gerenciado automaticamente pelo framework.
2. Criar o controlador REST
DemoController.java
@RestController
public class DemoController {
}
3. Criar o construtor para injetar a dependência
DemoController.java
@RestController
public class DemoController {
private Coach myCoach;
@Autowired
public DemoController(Coach theCoach) {
myCoach = theCoach;
}
}
@Autowired
diz ao Spring para injetar automaticamente a dependência.
Se houver apenas um construtor, a anotação é opcional.
4. Adicionar o endpoint /dailyworkout
@RestController
public class DemoController {
private Coach myCoach;
@Autowired
public DemoController(Coach myCoach) {
this.myCoach = myCoach;
}
@GetMapping("/dailyworkout")
public String getDailyWorkout() {
return myCoach.getDailyWorkout();
}
}