Spring 攻略第001讲续

5 篇文章 0 订阅
4 篇文章 0 订阅

继续上一讲···


为 Bean 配置集合

    List, Set 和 Map 是代表 Java 三种主要集合类型的核心接口,而对于每一种集合类型,Java都用不同函数和特性提供了多种可选的实现。在 Spring 中,这些集合类型可以轻松地用一组内建的XML 标记进行配置,例如 <List>、<Set>和 <Map>。

还是以上面的例子为例,但我们把sesametech.springrecipes.s001 复制为sesametech.springrecipes.s002,然后假设我们使用 java.util.List 集合来包含你的后缀,修改后的 SequenceGenerator 类代码片段如下:

packagesesametech.springrecipes.s002;

 

import java.util.List;

 

public class SequenceGenerator {

 

       private String prefix;

       private List<Object>suffixes;

       private int initial;

       private int counter;

 

       public SequenceGenerator() {

       }

 

       publicSequenceGenerator(Stringprefix, List<Object>suffixes, intinitial) {

              this.prefix =prefix;

              this.suffixes =suffixes;

              this.initial =initial;

       }

 

       public synchronized String getSequence(){

              StringBufferbuffer = new StringBuffer();

              buffer.append(prefix);

              buffer.append(initial +counter++);

              for (Object suffix : suffixes) {

                     buffer.append("-");

                     buffer.append(suffix);

              }

              return buffer.toString();

       }

 

       getter & setter …

}

 

    为了在Bean 配置中定义 java.util.List 接口的属性,必须指定一个包含元素的<list> 标记。<list> 标记中允许的元素可以是有<value> 指定的常量值、<ref> 指定的Bean 应用、<bean> 指定的内部 Bean、<idref> 指定的 ID 引用定义,或者 <null> 指定的空元素,甚至可以嵌入另一个集合。对于本示例的配置,这次我们首先把beans.xml 拷贝到 sesametech.springrecipes.s002 包下,然后修改如下:

       <bean

              id="sequenceGenerator"

              name="sequenceGenerator"

              class="sesametech.springrecipes.s002.SequenceGenerator">

              <propertyname="prefix"value="30"/>

              <propertyname="initial"value="100000"/>

              <propertyname="suffixes">

                     <list>

                           <value>A</value>

                           <beanclass="java.net.URL">

                                  <constructor-argvalue="http"/>

                                  <constructor-argvalue="www.sesametech.com"/>

                                  <constructor-argvalue="/"/>

                           </bean>

                           <null/>

                     </list>

              </property>

       </bean>

 

接下来,我们修改源码目录“sesametech.springrecipes.s002”包下名为 SequenceGeneratorTest 的测试类,修改后的main() 方法如下所示:

       public static void main(String[] args) {

              ApplicationContext context =new ClassPathXmlApplicationContext("sesametech/springrecipes/s002/beans.xml");

              SequenceGeneratorgenerator = (SequenceGenerator)context.getBean("sequenceGenerator");

              System.out.println(generator.getSequence());

              System.out.println(generator.getSequence());

       }

    注意这次我们加载配置文件路径变化,不是在源码根目录下了,而是在sesametech.springrecipes.s002 包下。

 

    在概念上,数组Array 近似于 List,它也是一组排序和索引的集合,可以用索引访问,主要的不同点在于数组的长度是固定的。因此,Bean的属性配置也是通过 <list> 标记实现。

 

    另一个常见的集合类型是java.util.Set。Set 和 List都扩展自统一个接口 java.util.Collection,不同点在于Set 既不排序也不索引,仅能存储独特的对象。为了定义 Set 类型的属性,可通过使用<set> 标记类实现。由于其用法法与 <list> 相同,因此不在举例,给出片段如下:

       <set>

              <value>A</value>

……

       </set>

 

Map 接口是一个在键值对(key/value)中存储项目的表。你可以通过关键字 key 从 Map 中取得特定的值,关键字和值可以是任何类型。关键字之间是否相等是由 equals() 方法确定。仍然以前面的例子为例,这次我们把包sesametech.springrecipes.s002复制为 sesametech.springrecipes.s003,然后假设我们使用java.util.Map 集合来包含你的后缀,修改后的 SequenceGenerator 代码片段如下:

packagesesametech.springrecipes.s002;

 

import java.util.List;

 

public class SequenceGenerator {

 

       private String prefix;

       private Map<Object,Object>suffixes;

       private int initial;

       private int counter;

 

       public SequenceGenerator() {

       }

 

       publicSequenceGenerator(Stringprefix, List<Object>suffixes, intinitial) {

              this.prefix =prefix;

              this.suffixes =suffixes;

              this.initial =initial;

       }

 

       public synchronized String getSequence(){

              StringBufferbuffer = new StringBuffer();

              buffer.append(prefix);

              buffer.append(initial +counter++);

              for (Entry<Object,Object>suffix :suffixes.entrySet()) {

                     buffer.append("-");

                     buffer.append(suffix.getKey());

                     buffer.append("@");

                     buffer.append(suffix.getValue());

              }

              return buffer.toString();

       }

 

       getter & setter …

}

    接下来,修改我们sesametech.springrecipes.s003 包下的 beans.xml 配置文件,片段如下所示:

       <bean

              id="sequenceGenerator"

              name="sequenceGenerator"

              class="sesametech.springrecipes.s003.SequenceGenerator">

              <propertyname="prefix"value="30"/>

              <propertyname="initial"value="100000"/>

              <propertyname="suffixes">

                     <map>

                           <entrykey="type"value="A"/>

                           <entrykey="url">

                                  <beanclass="java.net.URL">

                                         <constructor-argvalue="http"/>

                                         <constructor-argvalue="www.sesametech.com"/>

                                         <constructor-argvalue="/"/>

                                  </bean>

                           </entry>

                     </map>

              </property>

       </bean>

接着记得修改一下源码目录“sesametech.springrecipes.s003”包下名为 SequenceGeneratorTest 的测试类的main() 方法中的应用程序上下文的加载路径,如下所示:

ApplicationContext context = new ClassPathXmlApplicationContext("sesametech/springrecipes/s003/beans.xml");

 

有时候,可能会遇到要为 Map 实例配置一个 null 值的情况,Spring 对此提供了显式支持,例如:

       <propertyname="nulledMapValue">

              <map>

                     <entry>

                           <key> <value>null</value></key>

                     </entry>

              </map>

       </property>

 

java.util.Properties 集合非常近似于 java.util.Map,它也实现 java.util.Map接口,也是存储键值对(key/value)项目。唯一不同的是Properties 集合的键值对始终是字符串。在 Spring 中,可以通过使用<props> 标记来实现,以多个 <prop> 标记作为子项目,而每个<prop> 标记必须定义一个 key 属性并包含对应的属性值。还是以前面的例子为例,这次我们把包sesametech.springrecipes.s003复制为 sesametech.springrecipes.s004,然后假设我们使用java.util.Properties 集合来包含你的后缀,修改后的 SequenceGenerator 代码片段如下:

public class SequenceGenerator {

 

       ……

       private Properties suffixes;

 

       ……

}

 

接下来,修改我们sesametech.springrecipes.s004 包下的 beans.xml 配置文件,片段如下所示:

       <propertyname="suffixes">

              <props>

                     <propkey="type">A</prop>

                     <propkey="url">http://www.sesametech.com/</prop>

                     <propkey="null">null</prop>

              </props>

       </property>

最后不要忘记修改一下源码目录“sesametech.springrecipes.s004”包下名为 SequenceGeneratorTest 的测试类的main() 方法中的应用程序上下文的加载路径,如下所示:

ApplicationContext context = new ClassPathXmlApplicationContext("sesametech/springrecipes/s004/beans.xml");


合并父 Bean 的集合属性

如果你用继承定义 Bean,即为 <bean> 标记添加 parent 属性,那么子 Bean 的集合可以通过添加merge 属性并设置为 true 使其与父 Bean 的集合合并。

对于 List 集合,子 Bean 的集合将附加在父 Bean 的集合之后并保持顺序。以前面的例子为例,我们把包sesametech.springrecipes.s002 复制为sesametech.springrecipes.s005,然后修改我们sesametech.springrecipes.s005 包下的 beans.xml 配置文件,片段如下所示:

       <bean

              id="baseSequenceGenerator"

              class="sesametech.springrecipes.s005.SequenceGenerator">

              <property

                     name="prefix"

                     value="30" />

              <property

                     name="initial"

                     value="100000" />

              <property name="suffixes">

                     <list>

                           <value>A</value>

                           <value>B</value>

                     </list>

              </property>

       </bean>

 

       <bean

              id="sequenceGenerator"

              parent="baseSequenceGenerator"

              class="sesametech.springrecipes.s005.SequenceGenerator">

              <property

                     name="prefix"

                     value="40" />

              <property

                     name="initial"

                     value="200000" />

              <property name="suffixes">

                     <list merge="true">

                           <value>A</value>

                           <value>C</value>

                     </list>

              </property>

       </bean>

记得修改一下源码目录“sesametech.springrecipes.s005”包下名为 SequenceGeneratorTest 的测试类的main() 方法中的应用程序上下文的加载路径,如下所示:

ApplicationContext context = new ClassPathXmlApplicationContext("sesametech/springrecipes/s005/beans.xml");

然后我们运行这个测试类,会发现我们的序列发生器包含了4个后缀:A、B、A 和 C。

对于 Set 或Map 集合,如果有相同的值,子 Bean 的值将覆盖父Bean 的值。例如以下配置后的序列发生器将有 3个后缀:A、B 和 C:

       <bean

              id="baseSequenceGenerator"

              class="sesametech.springrecipes.s003.SequenceGenerator">

              <property

                     name="prefix"

                     value="30" />

              <property

                     name="initial"

                     value="100000" />

              <property name="suffixes">

                     <set>

                           <value>A</value>

                           <value>B</value>

                     </set>

              </property>

       </bean>

 

       <bean

              id="sequenceGenerator"

              parent="baseSequenceGenerator"

              class="sesametech.springrecipes.s003.SequenceGenerator">

              <property

                     name="prefix"

                     value="40" />

              <property

                     name="initial"

                     value="200000" />

              <property name="suffixes">

                     <set merge="true">

                           <value>A</value>

                           <value>C</value>

                     </set>

              </property>

       </bean>

由于不算太难,作为练习,读者可以以包“sesametech.springrecipes.s003”为蓝本,亲自动手试一试。


好了,今天就写到这里了,待续···

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值