为集合元素指定数据类型
默认情况下,Spring 将集合中的所有元素都当作字符串来对待。因此,如果你的集合元素不想被当作字符串的话,就必须为它们指定数据类型。
在 Spring 中,你可以使用<value> 标记的 type 属性指定每个集合元素的数据类型,也可以使用集合标记的value-type 属性一次性指定所有元素的类型。
另外,如果你使用 Java 5 或更高版本,则可以定义类型安全的集合,这样Spring 将可以读取集合的类型信息。
下面以前面讲到的序列生成器为例,假设我们打算接受一系列整数作为其后缀,每个数字都将使用 java.text.DecimalFormat 实例格式化为 4 位数字。为此,我们把前面讲到的“sesametech.springrecipes.s002”包拷贝成为“sesametech.springrecipes.s008”包,并按如下所示代码片段修改“SequenceGenerator”类的代码:
public class SequenceGenerator {
……
public synchronized String getSequence(){
StringBufferbuffer = new StringBuffer();
buffer.append(prefix);
buffer.append(initial + counter++);
DecimalFormatformatter = new DecimalFormat("0000");
for (Object suffix : suffixes) {
buffer.append("-");
buffer.append(formatter.format((Integer) suffix));
}
return buffer.toString();
}
}
接着修改一下该包下的 beans.xml 配置文件,如下所示:
<bean
id="sequenceGenerator"
name="sequenceGenerator"
class="sesametech.springrecipes.s008.SequenceGenerator">
<property name="prefix"value="30" />
<property name="initial"value="100000" />
<property name="suffixes">
<list>
<value>5</value>
<value>10</value>
<value>20</value>
</list>
</property>
</bean>
最后修改一下该包下的“SequenceGeneratorTest”测试类的应用程序上下文加载路径:
ApplicationContext context = newClassPathXmlApplicationContext("sesametech/springrecipes/s008/beans.xml");
若此时你运行这个测试程序,将会遇到一个“ClassCastException”异常,指出后缀不能转换为整数,因为其类型默认是 String 类型。
为解决此异常,我们必须设置 <value> 元素的 type 属性以指定元素类型。因此,我们再次修改beans.xml 配置文件,如下所示:
<bean
id="sequenceGenerator"
name="sequenceGenerator"
class="sesametech.springrecipes.s008.SequenceGenerator">
<property name="prefix"value="30" />
<property name="initial"value="100000" />
<property name="suffixes">
<list><!-- <listvalue-type="int"> -->
<value type="int">5</value>
<value type="int">10</value>
<value type="int">20</value>
</list>
</property>
</bean>
当然,你也可以一次性在 <list> 标签中指定 value-type 属性,这样就不用再在每一个<value> 标签中分别指定了。
现在再次运行测试程序,若无其他意外,应该一切正常了。
另外,如果你使用 Java 5 或更高版的话,我们可以用存储整数的类型安全集合来定义suffixes 列表,如下代码片段所示进行集合变量的声明:
public class SequenceGenerator {
……
private List<Object>suffixes;
……
}
一旦以类型安全的方式定义了集合,Spring 就能通过反射的方式来读取集合的类型信息了。这样的话,就不必指定<list> 的 value-type 属性或者每个<value> 的 type 属性了。
待续······