Autoware注入集合

在日常开发中,我们都会使用@Autowired来给bean进行属性注入。大多数情况下,注入的属性都是某一具体的单例bean,实际上,@Autowired还可以用来注入集合,如下:

1
2
3
4
5
6
7
/**userMap: key是bean名,value是bean实例*/
@Autowired
private Map<String, User> userMap;

/**userList: 类型是User的bean实例的集合*/
@Autowired
private List<User> userList;

在配置类中,加入三个User类的bean

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@Bean
public User user1(){
User user = new User();
user.setUsername("user1");
return user;
}

@Bean
public User user2(){
User user = new User();
user.setUsername("user2");
return user;
}

@Bean
public User user3(){
User user = new User();
user.setUsername("user3");
return user;
}

spring中,单例bean指的是bean的名称是唯一的,而不是bean的类型是唯一的。在上述创建三个User类的bean的例子中,创建的三个bean的名称分别是"user1""user2""user3"。但它们都是User类型。因为它们名称不一样,所以还是单例bean

然后能得到userMapuserList的值为:

image-20240321151858337

使用场景

一般来说,@Autoware注入集合在策略模式中使用的比较多。

例如:假设小明要去球馆打球,篮球要50元一天,乒乓球要100元一天,羽毛球要150元一天,那就要根据小明去打什么球来计算要花多少钱。

1
2
3
4
5
6
7
8
9
if ("basketball".equals(sportType)){
pay = 50;
}else if("pingpong".equals(sportType)){
pay = 100;
}else if("tennis".equals(sportType)){
pay = 150;
}else {
// 抛出错误
}

不过这种方法不好拓展。

另外一种方法是,我们可以抽象一个Sport接口

1
2
3
public interface Sport {
Integer getPay();
}

然后再提供篮球、乒乓球、羽毛球的实现类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
@Component(value = "basketball")
public class SportBasketball implements Sport {
@Override
public Integer getPay() {
return 50;
}
}

@Component(value = "pingpong")
public class SportPingpong implements Sport {
@Override
public Integer getPay() {
return 100;
}
}

@Component(value = "tennis")
public class SportTennis implements Sport {
@Override
public Integer getPay() {
return 150;
}
}

这样使用时,直接注入Sport类的集合,就能直接使用了

1
2
3
4
5
6
7
8
9
10
@Autowired
private Map<String, Sport> sportMap;

public void test(String sportType){
Sport sport = sportMap.get(sportType);
if (sport == null){
// 抛出错误
}
Integer pay = sport.getPay();
}

image-20240321162552986

如果再增加排球运动,直接加一个排球实现类即可。

要注意的是,注入Map时,key必须是String类型的,代表注入的bean的名称