15‐Defining Dependency Injection - JulianeMaran32/Java-with-Spring-Boot GitHub Wiki

32. Definindo Injeção de Dependência - Visão Geral - Parte 1

Injeção de Dependência

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.

Exemplo: Fábrica de Carros

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

Diagrama (Mermaid) – Fábrica de Carros

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
Loading

Contêiner do Spring

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

Diagrama (Mermaid) – Contêiner Spring

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
Loading

Exemplo Prático

  • Criamos uma interface Coach, que oferece treinos diários.
  • O controlador DemoController quer usar um Coach.
  • Coach é uma dependência do DemoController.
  • Precisamos injetar essa dependência com Spring.

Tipos de Injeção

O Spring oferece diferentes formas de injetar dependências. As mais recomendadas são:

  • Injeção via Construtor
  • Injeção via Setter

Qual tipo usar?

  • 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 que é Autowiring no Spring?

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.

Exemplo de Autowiring

  • Temos a interface Coach.
  • Temos uma classe CricketCoach com @Component.
  • O Spring detecta isso e injeta automaticamente onde for necessário.

33. Definindo Injeção de Dependência - Visão Geral - Parte 2

Exemplo de Aplicação

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"
Loading

Processo de Desenvolvimento – Injeção via Construtor (passo a passo)

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();
    }
}
⚠️ **GitHub.com Fallback** ⚠️