18‐Setter‐Injection - JulianeMaran32/Java-with-Spring-Boot GitHub Wiki

41. Injeção via Setter - Visão Geral

Tipos de Injeção no Spring

O Spring oferece dois principais tipos de injeção de dependência:

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

Neste tópico, vamos focar na injeção via setter, que consiste em passar dependências para sua classe por meio de métodos set.

Exemplo com Autowired

Vamos considerar o caso em que queremos injetar uma implementação da interface Coach.

  • O Spring fará a varredura por classes anotadas com @Component.
  • Encontrando uma classe que implemente Coach, como CricketCoach, ela será injetada automaticamente.

Por exemplo, no DemoController, queremos injetar um Coach.

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

  1. Crie métodos set em sua classe para receber a dependência.
  2. Use a anotação @Autowired para o Spring saber que deve injetar a dependência.

Passo 1: Criar o método setter


@RestController
public class DemoController {

    private Coach myCoach;

    public void setMyCoach(Coach myCoach) {
        this.myCoach = myCoach;
    }

    // ...
}

Passo 2: Usar a anotação @Autowired no método setter


@RestController
public class DemoController {

    private Coach myCoach;

    @Autowired
    public void setMyCoach(Coach myCoach) {
        this.myCoach = myCoach;
    }

    // ...
}

Com isso, o Spring irá cuidar da injeção da dependência nos bastidores.

Como o Spring processa sua aplicação

Interface: Coach.java

public interface Coach {
    String getDailyWorkout();
}

Implementação: CricketCoach.java


@Component
public class CricketCoach implements Coach {

    @Override
    public String getDailyWorkout() {
        return "Pratique arremessos rápidos por 15 minutos!";
    }
}

Controlador: DemoController.java


@RestController
public class DemoController {

    private Coach myCoach;

    @Autowired
    public void setMyCoach(Coach myCoach) {
        this.myCoach = myCoach;
    }
}

Simulação do que o Spring faz internamente

Coach theCoach = new CricketCoach();
DemoController demoController = new DemoController();
demoController.

setMyCoach(theCoach);

Você também pode usar qualquer nome de método para fazer a injeção, não precisa ser necessariamente set....


@RestController
public class DemoController {

    private Coach myCoach;

    @Autowired
    public void doSomeStuff(Coach theCoach) {
        this.myCoach = theCoach;
    }
}

Qual tipo de injeção devo usar?

  • Injeção via Construtor

    • Use quando a dependência for obrigatória.
    • É a abordagem recomendada oficialmente pelo time do Spring.
  • Injeção via Setter

    • Use quando a dependência for opcional.
    • Se o Spring não injetar nada, sua aplicação pode usar um valor padrão.

42. Injeção via Setter - Codificação

Preparação

Antes de começar:

  • Pare todas as aplicações rodando.
  • Feche janelas do projeto.
  • Reconstrua o projeto (isso ajuda o Spring a recarregar tudo corretamente).

Etapas da Codificação

1. Crie o método setter para a dependência
2. Use @Autowired no método setter

Primeiro, remova a injeção via construtor, se existir:

// Remova este trecho
@Autowired
public DemoController(Coach myCoach) {
    this.myCoach = myCoach;
}

Criação da implementação CricketCoach:


@Component
public class CricketCoach implements Coach {

    @Override
    public String getDailyWorkout() {
        return "Pratique arremessos rápidos por 15 minutos! :-)";
    }
}

Classe DemoController com Setter Tradicional:


@RestController
public class DemoController {

    private Coach myCoach;

    @Autowired
    public void setMyCoach(Coach myCoach) {
        this.myCoach = myCoach;
    }

    @GetMapping("/dailyworkout")
    public String getDailyWorkout() {
        return myCoach.getDailyWorkout();
    }
}

Exemplo usando método com nome alternativo:


@RestController
public class DemoController {

    private Coach myCoach;

    @Autowired
    public void doSomeStuff(Coach myCoach) {
        this.myCoach = myCoach;
    }

    @GetMapping("/dailyworkout")
    public String getDailyWorkout() {
        return myCoach.getDailyWorkout();
    }
}

Você pode dar qualquer nome ao método anotado com @Autowired, desde que ele receba como parâmetro o tipo correto da dependência. O Spring se encarregará da injeção.

Resumo

  • A injeção via setter é útil para dependências opcionais.
  • Você pode usar qualquer nome de método, não precisa seguir o padrão set....
  • Basta anotar com @Autowired, e o Spring fará o trabalho para você.

43 Injeção de Dependência via Campo (Field Injection)

Tipos de Injeção no Spring

O Spring permite injetar dependências de três formas principais:

  • Injeção via Construtor:
    • Recomendada pela equipe do [spring.io]
    • Ideal para dependências obrigatórias
  • Injeção via Setter:
    • Também recomendada
    • Boa opção para dependências opcionais
  • Injeção via Campo (Field Injection):
    • Não recomendada pela equipe do [spring.io]
    • Ainda presente em códigos mais antigos

Por que a Injeção via Campo não é recomendada?

Antigamente, a injeção via campo era comum em projetos Spring. No entanto, atualmente ela caiu em desuso por vários motivos:

  • Dificulta os testes unitários Como os campos são privados e não há construtores ou métodos set, é mais complicado simular dependências durante os testes.

  • Menor controle sobre a inicialização A injeção acontece "por trás dos panos", o que pode dificultar o entendimento do código.

  • Boa prática atual Usar injeção via construtor ou via setter é mais claro, testável e robusto.

Apesar disso, ainda é possível encontrar injection via campo em:

  • Projetos legados (mais antigos)
  • Blogs, artigos ou vídeos antigos
  • Versões anteriores de cursos (incluindo este)

O que é Injeção via Campo?

Na injeção via campo, o Spring injeta a dependência diretamente no atributo da classe, mesmo se ele for private.
Isso é feito internamente usando Java Reflection.
Você não precisa criar um construtor ou método set, basta anotar o atributo com @Autowired.

Exemplo: Field Injection com @Autowired


@RestController
public class DemoController {

    @Autowired
    private Coach myCoach; // Injeção via campo

    @GetMapping("/dailyworkout")
    public String getDailyWorkout() {
        return myCoach.getDailyWorkout();
    }
}

Nesse exemplo:

  • O Spring identifica o campo myCoach
  • Encontra uma implementação da interface Coach (por exemplo, CricketCoach)
  • Injeta essa implementação automaticamente, mesmo sendo um campo privado

Observações importantes

  • Evite usar a injeção via campo em novos projetos.
  • Prefira injeção via construtor ou via setter, conforme o contexto.
  • A injeção via campo ainda pode aparecer em códigos antigos, então é importante conhecê-la.

Conclusão

Tipo de Injeção Recomendado? Quando usar
Via Construtor Sim Para dependências obrigatórias
Via Setter Sim Para dependências opcionais
Via Campo (Field) Não Apenas para leitura/manutenção de código legado