Spring @Primary Annotation
1. Vue d'ensemble
Dans ce rapide didacticiel, nous aborderons l'annotation@Primary de Spring qui a été introduite avec la version 3.0 du framework.
En termes simples,we use @Primary to give higher preference to a bean when there are multiple beans of the same type.
Décrivons le problème en détail.
2. Pourquoi@Primary est-il nécessaire?
Dans certains cas,we need to register more than one bean of the same type.
Dans cet exemple, nous avons les beansJohnEmployee() etTonyEmployee() de typeEmployee:
@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.
Pour accéder aux beans du même type, nous utilisons généralement l'annotation@Qualifier(“beanName”).
Nous l'appliquons au point d'injection avec@Autowired. Dans notre cas, nous sélectionnons les beans lors de la phase de configuration afin que@Qualifier ne puisse pas être appliqué ici. Nous pouvons en savoir plus sur l'annotation@Qualifier en suivant leslink.
Pour résoudre ce problème, Spring propose l'annotation@Primary.
3. Utiliser@Primary avec@Bean
Jetons un œil à la classe de configuration:
@Configuration
public class Config {
@Bean
public Employee JohnEmployee() {
return new Employee("John");
}
@Bean
@Primary
public Employee TonyEmployee() {
return new Employee("Tony");
}
}
On marqueTonyEmployee() bean avec@Primary. Spring injectera le haricotTonyEmployee() de préférence sur le haricotJohnEmployee().
Maintenant, démarrons le contexte de l'application et récupérons le beanEmployee à partir de celui-ci:
AnnotationConfigApplicationContext context
= new AnnotationConfigApplicationContext(Config.class);
Employee employee = context.getBean(Employee.class);
System.out.println(employee);
Après avoir exécuté l'application:
Employee{name='Tony'}
From the output, we can see that the TonyEmployee() instance has a preference while autowiring.
4. Utiliser@Primary avec@Component
We can use @Primary directly on the beans. Examinons le scénario suivant:
public interface Manager {
String getManagerName();
}
Nous avons une interfaceManager et deux beans de sous-classe,DepartmentManager:
@Component
public class DepartmentManager implements Manager {
@Override
public String getManagerName() {
return "Department manager";
}
}
Et le beanGeneralManager:
@Component
@Primary
public class GeneralManager implements Manager {
@Override
public String getManagerName() {
return "General manager";
}
}
Ils remplacent tous les deux lesgetManagerName() de l'interfaceManager. Notez également que nous marquons leGeneralManager bean avec@Primary.
Cette fois,@Primary only makes sense when we enable the component scan:
@Configuration
@ComponentScan(basePackages="org.example.primary")
public class Config {
}
Créons un service pour utiliser l'injection de dépendances tout en trouvant le bon bean:
@Service
public class ManagerService {
@Autowired
private Manager manager;
public Manager getManager() {
return manager;
}
}
Ici, les deux beansDepartmentManager andGeneralManager sont éligibles pour l'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());
La sortie est «General manager”.
5. Conclusion
Dans cet article, nous avons découvert l'annotation@Primary de Spring. Avec les exemples de code, nous avons démontré le besoin et les cas d'utilisation des@Primary.
Comme d'habitude, le code complet de cet article est disponibleover on GitHub project.