20‐Primary - JulianeMaran32/Java-with-Spring-Boot GitHub Wiki
47. Primary - Visão Geral
Anotação @Primary
Quando temos várias implementações de uma interface
- Suponha que tenhamos várias classes que implementam a interface
Coach
.
- Anteriormente, resolvemos isso usando a anotação
@Qualifier
para indicar exatamente qual classe usar.
- Mas existe uma alternativa...
Solução Alternativa
- Em vez de dizer explicitamente qual classe usar com
@Qualifier
, podemos apenas dizer:
- "Preciso de um
Coach
, qualquer um serve."
- A ideia é: se houver várias opções, deixamos o Spring escolher uma como a principal (ou “primária”).
- Isso é feito usando a anotação
@Primary
.
Exemplo com Várias Implementações de Coach
@Component
@Primary // Esta é a implementação padrão de Coach
public class TrackCoach implements Coach {
public String getDailyWorkout() {
return "Corra uma prova intensa de 5km!";
}
}
@Component
public class CricketCoach implements Coach {}
@Component
public class BaseballCoach implements Coach {}
@Component
public class TennisCoach implements Coach {}
@RestController
public class DemoController {
private Coach myCoach;
// Não precisamos usar @Qualifier
// O Spring vai usar o Coach marcado com @Primary
@Autowired
public DemoController(Coach myCoach) {
this.myCoach = myCoach;
}
@GetMapping("/dailyworkout")
public String getDailyWorkout() {
return myCoach.getDailyWorkout();
}
}
Regras do @Primary
- Você só pode marcar uma única classe como
@Primary
.
- Se marcar mais de uma, o Spring não saberá qual usar e gerará um erro:
Unsatisfied dependency expressed through constructor parameter 0:
No qualifying bean of type 'Coach' available:
more than one 'primary' bean found among candidates: [baseballCoach, cricketCoach, tennisCoach, trackCoach]
Misturando @Primary
com @Qualifier
- É possível usar os dois juntos.
- Porém, o
@Qualifier
tem prioridade maior que o @Primary
.
@RestController
public class DemoController {
private Coach myCoach;
@Autowired
public DemoController(@Qualifier("cricketCoach") Coach myCoach) {
this.myCoach = myCoach;
}
@GetMapping("/dailyworkout")
public String getDailyWorkout() {
return myCoach.getDailyWorkout();
}
}
@Primary
@Component
public class TrackCoach implements Coach {
public String getDailyWorkout() {
return "Corra uma prova intensa de 5km!";
}
}
Qual usar: @Primary
ou @Qualifier
?
@Primary
: Deixa o Spring escolher a implementação padrão.
- Pode causar erro se mais de uma classe estiver marcada como
@Primary
.
@Qualifier
: Você escolhe exatamente qual classe usar.
- Mais seguro e específico.
- Tem prioridade maior do que
@Primary
.
- Recomendação: Prefira usar
@Qualifier
sempre que quiser mais controle e clareza.
48. Primary - Codificando
@RestController
public class DemoController {
private Coach myCoach;
@Autowired
public DemoController(Coach myCoach) {
this.myCoach = myCoach;
}
@GetMapping("/dailyworkout")
public String getDailyWorkout() {
return myCoach.getDailyWorkout();
}
}
@Primary
@Component
public class TrackCoach implements Coach {
@Override
public String getDailyWorkout() {
return "Corra uma prova intensa de 5km!";
}
}
Resultado: Sucesso!
- A aplicação inicia normalmente.
- Mesmo com várias implementações da interface
Coach
, o Spring escolhe a classe TrackCoach
, pois está anotada com @Primary
.
- Quando acessamos a URL
http://localhost:8080/dailyworkout
, recebemos a resposta da TrackCoach
.