Spring中@Primary注解

1.概述

讨论Spring的@Primary注解,该注解是框架在3.0版中引入的。

其作用与功能,当有多个相同类型的bean时,使用@Primary来赋予bean更高的优先级

2.为什么需要@Primary?

在某些情况下,需要注册多个相同类型的bean。

在此示例中,有Employee类型的zhangSanEmployee()和liSiEmployee()Bean:

 1 @Configuration
 2 public class PrimaryConfig {
 3     @Bean
 4     public Employee zhangSanEmployee() {
 5         return new Employee("张三");
 6     }
 7 
 8     @Bean
 9     public Employee liSiEmployee() {
10         return new Employee("李四");
11     }
12 }

如果尝试运行应用程序,与@Autowired一起应用于注入。Spring会抛出NoUniqueBeanDefinitionException。

要访问相同类型的bean,常使用@Qualifier(“beanName”)注解,通过别名控制访问相同类型。

 1 @Configuration
 2 public class PrimaryConfig {
 3 
 4    @Bean
 5    @Qualifier("zhangSanEmployee")
 6    public Employee zhangSanEmployee() {
 7        return new Employee("张三");
 8    }
 9 
10    @Bean
11    @Qualifier("liSiEmployee")
12    public Employee liSiEmployee() {
13        return new Employee("李四");
14    }
15 }

注入

1 @Resource
2 private Employee zhangSanEmployee;
3 
4 @Resource
5 private Employee liSiEmployee;

3.将@Primary和@Bean一起使用

看一下配置类:

 1 @Configuration
 2 public class PrimaryConfig {
 3 
 4     @Bean
 5     public Employee zhangSanEmployee() {
 6         return new Employee("张三");
 7     }
 8 
 9     @Bean
10     @Primary
11     public Employee liSiEmployee() {
12         return new Employee("李四");
13     }
14 }

用@Primary标记liSiEmployee()bean。 Spring将优先于zhangSanEmployee()注入liSiEmployee()bean。

1 @Test
2 public void test1() {
3     AnnotationConfigApplicationContext context
4         = new AnnotationConfigApplicationContext(PrimaryConfig.class);
5 
6     Employee employee = context.getBean(Employee.class);
7     System.out.println(employee);//Employee(name=李四)
8 
9 }

4.将@Primary与@Component一起使用

可以直接在bean上使用@Primary。

1 public interface Manager {
2     String getManagerName();
3 }

有一个Manager接口和两个子类bean

1 @Component
2 public class DepartmentManager implements Manager {
3     @Override
4     public String getManagerName() {
5         return "Department manager";
6     }
7 }
1 @Component
2 @Primary
3 public class GeneralManager implements Manager {
4     @Override
5     public String getManagerName() {
6         return "General manager";
7     }
8 }

都覆盖Manager接口的getManagerName()。 另外,请注意,用@Primary标记了GeneralManager bean。

 1 @Service
 2 public class ManagerService {
 3 
 4     @Autowired
 5     private Manager manager;
 6 
 7     public Manager getManager() {
 8         return manager;
 9     }
10 }

测试

 1 @RunWith(SpringRunner.class)
 2 @SpringBootTest
 3 public class PrimaryTest {
 4     @Resource
 5     private ApplicationContext context;
 6     @Test
 7     public void test2() {
 8         ManagerService service = context.getBean(ManagerService.class);
 9         Manager manager = service.getManager();
10         System.out.println(manager.getManagerName());//General manager
11     }
12 }

 

posted @ 2022-10-18 19:47  Boblim  阅读(162)  评论(0编辑  收藏  举报