大家好,我是Hydra。Spring作为项目中不可或缺的底层框架,提供了最基本的bean管理功能。Bean注入相信大家都不陌生,但是有几种集合注入方式并不常用,可能有些同学不是很了解。今天我们就通过实例来看看它的使用。首先声明一个接口:publicinterfaceUserDao{StringgetName();}然后定义两个类分别实现这个接口,通过@Component注解把bean放到spring容器中:@ComponentpublicclassUserDaoAimplementsUserDao{@OverridepublicStringgetName(){返回“九头蛇”;}}@ComponentpublicclassUserDaoBimplementsUserDao{@OverridepublicStringgetName(){return"#公众号:码农进上";有两种不同类型的集合注入。Map注入先看Map类型的注入,直接在Service中注入一个Map,key是字符串类型,value是上面定义的接口类型。@Service@AllArgsConstructorpublicclassUserMapService{finalMapuserDaoMap;publicMapgetDaos(){返回userDaoMap;}}通过接口测试查看这个Map的内容:可以看到value是一个实现接口的实例对象,key是beanName,可以通过@Component的value属性自定义。修改UserDaoA,指定名称:@Component(value="Hydra")publicclassUserDaoAimplementsUserDao{...}可以看到key的值发生了变化:List注入到Service中,这次注入generic是List类型的接口UserDao。@Service@AllArgsConstructorpublicclassUserListService{privatefinalListuserDaoLists;publicListgetDaos(){返回userDaoLists;}}测试这个方法,查看List的内容,也就是我们放入容器中的两个bean:做吗?很简单,修改注入spring容器的两个bean,给它们加上@Order注解并指定加载顺序,数字越小优先级越高。@Component@Order(1)publicclassUserDaoAimplementsUserDao{……}@Component@Order(-1)publicclassUserDaoBimplementsUserDao{……}修改完成后,再次测试,可以看到顺序beans的变化:Set注入同样,无序Set也可以用来注入bean,泛型指定为接口类型。@Service@AllArgsConstructorpublicclassUserSetService{privatefinalSetuserDaoSet;publicSetgetDaos(){返回userDaoSet;}}查看Set中的元素,和List一样,只是顺序变乱了,不是因为@Order注解的值改变了:数组注入最后我们看一下数组注入方式:@Service@AllArgsConstructorpublicclassUserArrayService{privatefinalUserDao[]userDaoArray;publicUserDao[]getDaos(){返回userDaoArray;}}查看数组中的元素:并且和List类似,bean在数组中的排序会受到@Order注解的值的影响。有兴趣的同学可以自行尝试。应用理解这些注入方式后,简单提一下它的使用场景。比如我们可以使用Map注入实现策略模式来代替代码中复杂的if/else判断。例如,原代码中的判断逻辑可能是这样的:publicStringchoice(Stringname){if(name.equals("auth")){return"Hydra";}elseif(name.equals("official")){return"#公众号:码农进上";}returnnull;}使用策略模式进行改造,首先修改beanName:@Component(value="auth")publicclassUserDaoAimplementsUserDao{@OverridepublicStringgetName(){return"Hydra";}}@Component(value="official")publicclassUserDaoBimplementsUserDao{@OverridepublicStringgetName(){return"#公众号:码农进上";}}然后修改Servie方法,一行代码即可实现原来的if/else判断:@Service@AllArgsConstructorpublicclassTestService{finalMapuserDaoMap;publicStringchoice2(Stringname){returnuserDaoMap.get(name).getName();};}可能在这个例子中,这种写法的优势不是很明显,但是当你有一个很长的if/else判断时,这种模式可以让你的代码看起来简洁很多,并且符合以下原则根据功能进行代码拆分。同理,如果你通过@Order注解定义了bean的加载顺序,也可以理解为bean的优先级。比如我要调用符合类型的优先级最高的bean的方法,那么可以这样写:@Service@AllArgsConstructorpublicclassTestService{finalListuserDaoLists;publicStringchoiceFirst(){返回userDaoLists.get(0).getName();};}通过上面两个简单的例子,我们可以看出集合注入的方法使用起来非常灵活,我们可以在实际使用中结合各种设计模式,写出实用又优雅的代码。