20‐Primary - JuhMaran/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.