Anotação Primária @ Spring
1. Visão geral
Neste tutorial rápido, discutiremos a anotação de@Primary do Spring que foi introduzida com a versão 3.0 do framework.
Simplificando,we use @Primary to give higher preference to a bean when there are multiple beans of the same type.
Vamos descrever o problema em detalhes.
2. Por que@Primary é necessário?
Em alguns casos,we need to register more than one bean of the same type.
Neste exemplo, temosJohnEmployee()eTonyEmployee() beans do tipoEmployee:
@Configuration
public class Config {
@Bean
public Employee JohnEmployee() {
return new Employee("John");
}
@Bean
public Employee TonyEmployee() {
return new Employee("Tony");
}
}
Spring throws NoUniqueBeanDefinitionException if we try to run the application.
Para acessar beans com o mesmo tipo, geralmente usamos a anotação@Qualifier(“beanName”).
Nós o aplicamos no ponto de injeção junto com@Autowired. Em nosso caso, selecionamos os beans na fase de configuração, portanto@Qualifier não pode ser aplicado aqui. Podemos aprender mais sobre a anotação@Qualifier seguindo olink.
Para resolver esse problema, o Spring oferece a anotação@Primary.
3. Use@Primary com@Bean
Vamos dar uma olhada na classe de configuração:
@Configuration
public class Config {
@Bean
public Employee JohnEmployee() {
return new Employee("John");
}
@Bean
@Primary
public Employee TonyEmployee() {
return new Employee("Tony");
}
}
Marcamos o beanTonyEmployee() com@Primary. O Spring injetaráTonyEmployee() bean preferencialmente sobre oJohnEmployee().
Agora, vamos iniciar o contexto do aplicativo e obter o beanEmployee dele:
AnnotationConfigApplicationContext context
= new AnnotationConfigApplicationContext(Config.class);
Employee employee = context.getBean(Employee.class);
System.out.println(employee);
Depois de executar o aplicativo:
Employee{name='Tony'}
From the output, we can see that the TonyEmployee() instance has a preference while autowiring.
4. Use@Primary com@Component
We can use @Primary directly on the beans. Vamos dar uma olhada no seguinte cenário:
public interface Manager {
String getManagerName();
}
Temos uma interfaceManager e dois beans de subclasse,DepartmentManager:
@Component
public class DepartmentManager implements Manager {
@Override
public String getManagerName() {
return "Department manager";
}
}
E o feijãoGeneralManager:
@Component
@Primary
public class GeneralManager implements Manager {
@Override
public String getManagerName() {
return "General manager";
}
}
Ambos substituem ogetManagerName() da interfaceManager. Além disso, observe que marcamos oGeneralManager bean com@Primary.
Desta vez,@Primary only makes sense when we enable the component scan:
@Configuration
@ComponentScan(basePackages="org.example.primary")
public class Config {
}
Vamos criar um serviço para usar injeção de dependência enquanto encontramos o bean certo:
@Service
public class ManagerService {
@Autowired
private Manager manager;
public Manager getManager() {
return manager;
}
}
Aqui, ambos os beansDepartmentManager andGeneralManager são elegíveis para autowiring.
As we marked GeneralManager bean with @Primary, it will be selected for dependency injection:
ManagerService service = context.getBean(ManagerService.class);
Manager manager = service.getManager();
System.out.println(manager.getManagerName());
A saída é “General manager”.
5. Conclusão
Neste artigo, aprendemos sobre a anotação@Primary de Spring. Com os exemplos de código, demonstramos a necessidade e os casos de uso de@Primary.
Como de costume, o código completo deste artigo está disponívelover on GitHub project.