没想到吧,Spring中还有一招集合注入的写法

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了没想到吧,Spring中还有一招集合注入的写法相关的知识,希望对你有一定的参考价值。

参考技术A Spring作为项目中不可缺少的底层框架,提供的最基础的功能就是bean的管理了。bean地注入相信大家都比较熟悉了,但是有几种不太常用到的集合注入方式,可能有的同学会不太了解,今天我们就通过实例看看它的使用。

然后定义两个类来分别实现这个接口,并通过@Component注解把bean放入spring容器中:

准备工作完成后,我们看看几种不同类型的集合注入方式。

首先来看Map类型的注入,直接在Service中注入一个Map,key为字符串类型,value为上面定义的接口类型。

通过接口测试,查看这个Map中的内容:

可以看到,Map中的value是实现了接口的实例对象,key则是beanName,可以通过@Component的value属性进行自定义。

修改UserDaoA,指定名称:

可以看到,key的价值发生了改变:

在Service中,这次注入泛型为接口UserDao类型的List。

测试这个方法,查看List中的内容,是我们放入容器中的两个bean:

我们知道,List是一个有序的数据结构,那么如果想要修改List中bean的排序,该如何做呢?

很简单,修改注入到spring容器中的两个bean,为它们添加@Order注解并指定加载顺序,数字越小越优先加载。

修改完成后,再进行测试,可以看到bean的顺序发生了改变:

同样,也可以使用无序的Set注入bean,泛型指定为接口类型。

查看Set中的元素,和List相同,只不过顺序变为无序,不会因为@Order注解的值而改变:

最后,我们再来看一下数组注入的方式:

查看数组中的元素:

并且,和List比较类似的,数组中bean的排序会受到@Order注解数值的影响,有兴趣的同学可以自己尝试一下。

了解了这几种注入方式后,再简单提一下它的使用场景。例如,我们可以用Map注入实现策略模式,来替换代码中繁杂的if/else判断。例如,原始的代码中判断逻辑可能是这样的:

使用策略模式进行改造,首先修改beanName:

再修改Servie中的方法,一行代码即可实现原有的if/else判断:

可能在这个例子中,这种写法的优点体现得不十分明显,但是当你有一个非常长的if/else判断时,这种模式能使你的代码看上去简洁很多,并且符合代码按照功能拆分的原则。

同理,如果你已经通过@Order注解定义好了bean的加载顺序,也可以将它理解为bean的优先级,例如我想要调用优先级最高的符合类型的bean的方法,那么完全可以这样写:

通过上面两个简单的例子可以看到,集合注入的方式使用起来非常灵活,我们可以在实际使用中,结合各种设计模式,写出实用而优雅的代码。

Spring各类集合注入

参考技术A 原文: Spring各类集合注入
摘要: 我们常在Spring的Bean中注入各种基本类型的值和对象引用,如果需要注入List,Map,Set和数组等集合类型时,又该如何配置呢?
先定义一个测试类,由于本文将要介绍注入各种集合时如何配置,故这个类包含各种集合,类名和属性名不好取,没有特殊含义:
public class Test private List<String> listTest; private Map<String, Object> mapTest; private Set setTest; private String[] arrayTest; private Properties propertiesTest; //下面是各个属性的setter,此处省略 //......
Test类中,分别定义了List,Map,Set,Array等5种集合类型的属性,下面在Spring配置文件中,分别为这些类型的属性注入值:
`<bean id="test" class="com.abc.Test">

<property name="listTest">

<list>

<value>ListA</value>
<value>ListB</value>
<value>ListC</value>
</list>
</property>

</bean>`

由于集合元素有可以是基本类型值、引用容器中其他Bean、嵌套Bean或集合属性等,因此<list>、<set>、和<key>元素又可以接受如下的子元素:

<props>元素适用于配置Properties类型的属性,Properties类型时一种特殊的类型,其key和value都只能是字符串,故Spring配置Properties类型的属性都比较简单:每个属性项只要分别给出属性名和属性值就足够了。

当使用<map>元素配置Map类型属性时稍显复杂,因为Map类型的元素由多个<entry>组成,每个<entry>又需要配置key和value两个属性。其中<entry>属性支持以下几个属性:

<property name="propertiesTest"> <value> key1=value1 key2=value2 </value> </property>

虽然这种配置方式更简单,但是它也有一个缺点:属性名、属性值都只能是英文或数字,不能包含中文字符

从Spring2开始,Spring IoC容器支持集合的合并:子Bean中的集合属性可以从其父Bean的集合属性继承而来,同时,子Bean中的属性会覆盖父Bean中属性名相同的值。也就是说,子Bean的集合属性的最终值是父Bean、子Bean合并后的最终结果,下面是一个示例:
``
<bean id="parent" abstract="true" class="com.abc.Parent"> <property name="websites"> <props> <prop key="baidu">www.baidu.com</props> <prop key="google">www.google.com.hk</prop> <props> </property> </bean>
<bean id="child" parent="parent"> <property name="websites"> <props merge="true"> <prop key="google">www.google.com</prop> <prop key="tencent">www.qq.com</prop> <props> </property> </bean>
通过上面的配置后,child中的属性将变为:
baidu=www.baidu.com google=www.google.com tencent=www.qq.com

以上是关于没想到吧,Spring中还有一招集合注入的写法的主要内容,如果未能解决你的问题,请参考以下文章

你不会还在用这8个错误的SQL写法吧?

Zxing 的集成 ---- Maven 对应 Gradle 的写法

关于spring@Resource注解的问题

数据库安全之什么是SQL注入?

Spring Properties整理

SpringBoot java配置类@Configuration 的两种写法