可以为<constructor-arg>元素指定type和index属性,帮助Spring查找预期的构造程序。最新版的Spring也可以使用name属性。
(1)第一种情况
/* * Copyright 2013-2015 */ package com.jackie.codeproject.springrecipesnote.springioc; /** * Title: SequenceGenerator.java 类的功能说明 * * @author jackie * @since Apr 13, 2013 12:56:57 PM * @version V1.0 */ public class SequenceGenerator { /** * @Fields prefix : 前缀 */ private String prefix; /** * @Fields suffix : 后缀 */ private String suffix; /** * @Fields initial : 初始值 */ private int initial; /** * @Fields counter : 计数器 */ private int counter; /** * 获取序列号,声明为同步,使其成为线程安全的方法 * @author jackie * @date Apr 13, 2013 * @return * @return String */ public synchronized String getSquence() { StringBuffer buffer = new StringBuffer(); buffer.append(prefix); buffer.append(initial + counter++); buffer.append(suffix); return buffer.toString(); } /** * <p>Title: </p> * <p>Description:构造函数1 </p> * @param prefix * @param suffix * @param initial */ public SequenceGenerator(String prefix, String suffix, int initial) { this.prefix = prefix; this.suffix = suffix; this.initial = initial; } /** * <p>Title: </p> * <p>Description:构造函数2 </p> * @param prefix * @param suffix */ public SequenceGenerator(String prefix, String suffix) { this.prefix = prefix; this.suffix = suffix; } /** * <p>Title: </p> * <p>Description:构造函数3 </p> * @param prefix * @param initial */ public SequenceGenerator(String prefix, int initial) { this.prefix = prefix; this.initial = initial; } /** * @param prefix * the prefix to set */ public void setPrefix(String prefix) { this.prefix = prefix; } /** * @param suffix * the suffix to set */ public void setSuffix(String suffix) { this.suffix = suffix; } /** * @param initial * the initial to set */ public void setInitial(int initial) { this.initial = initial; } }
Bean配置文件:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd"> <bean id="sequenceGenerator" class="com.jackie.codeproject.springrecipesnote.springioc.SequenceGenerator"> <constructor-arg value="30" /> <constructor-arg value="100000" /> <property name="suffix" value="A" /> </bean> </beans>
测试程序:
// 使用ClassPathXmlApplicationContext是ApplicationContext接口的一个实现,它可以从classpath中装入一个XML配置文件 ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml"); // 使用getBean方法并为其传递配置的唯一的Bean名称,其返回类型为Object,须强制转型。 SequenceGenerator sequenceGenerator = (SequenceGenerator) applicationContext.getBean("sequenceGenerator"); System.out.println(sequenceGenerator.getSquence()); System.out.println(sequenceGenerator.getSquence());
输出结果:300A
301A
分析:出现这种结果的原因是调用了带有prefix和suffix参数的构造程序,而不是带有prefix和initial参数的。因为Spring默认将两个参数都解析为String类型,第一个构造程序不需要类型转换,所以被认定最合适。为了指定参数的预期类型,你必须设置<constructor-arg>中的type属性。
<bean id="sequenceGenerator" class="com.jackie.codeproject.springrecipesnote.springioc.SequenceGenerator"> <constructor-arg type="java.lang.String" value="30" /> <constructor-arg type="int" value="100000" /> <property name="suffix" value="A" /> </bean>
(2)第二种情况
在SequenceGenerator中再添加以下构造函数:
/** * <p>Title: </p> * <p>Description: </p> * @param suffix * @param initial */ public SequenceGenerator(int initial, String suffix) { this.suffix = suffix; this.initial = initial; }
修改Bean配置文件:
<bean id="sequenceGenerator" class="com.jackie.codeproject.springrecipesnote.springioc.SequenceGenerator"> <constructor-arg type="int" value="100000" /> <constructor-arg type="java.lang.String" value="A" /> <property name="prefix" value="30" /> </bean>
书上说再次运行测试程序可能得到正确结果,或者得到以下意外结果:
30100000null
30100000null
原因是Spring认为SequenceGenerator(String prefix, int initial) 和SequenceGenerator(int initial, String suffix)这两个构造函数是一样的,不会考虑参数出现在XML中的顺序,所以会造成歧义。但是我本人的程序跑起来都是使用的SequenceGenerator(int initial, String suffix),不知是不是最新版的Spring考虑了参数在XML文件中的位置,如有知道的牛人麻烦告知一声。
可以使用<constructor-arg>的index属性明确指出参数索引值。设置了type和Index属性,Spring就能够准确的为Bean找到预期的构造函数。
<bean id="sequenceGenerator" class="com.jackie.codeproject.springrecipesnote.springioc.SequenceGenerator"> <constructor-arg type="int" index="0" value="100000" /> <constructor-arg type="java.lang.String" index="1" value="A" /> <property name="prefix" value="30" /> </bean>
最简单的还是使用<constructor-arg>的name属性:
<bean id="sequenceGenerator" class="com.jackie.codeproject.springrecipesnote.springioc.SequenceGenerator"> <constructor-arg name="initial" value="100000" /> <constructor-arg name="suffix" value="A" /> <property name="prefix" value="30" /> </bean>
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)