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
, comoCricketCoach
, ela será injetada automaticamente.
Por exemplo, no DemoController
, queremos injetar um Coach
.
Processo de Desenvolvimento – Injeção via Setter (passo a passo)
- Crie métodos
set
em sua classe para receber a dependência. - 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;
}
// ...
}
@Autowired
no método setter
Passo 2: Usar a anotação
@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
.
@Autowired
Exemplo: Field Injection com
@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 |