Spring 攻略第003讲
来源:互联网 发布:mac支持的大型网游 编辑:程序博客网 时间:2024/06/05 08:16
指定Bean 引用
组成应用程序的 Bean 往往需要相互协作才能完成应用任务。为了Bean 之间的相互访问,你必须在 Bean 配置文件中指定Bean 引用。为此,Spring 提供了 <ref>标签为 Bean 属性或者构造方法参数指定 Bean 引用。
回忆一下之前的序列生成器示例,其前缀只接受字符串值,这样的灵活性不足以满足将来的要求。如果前缀的生成可以由某种编程逻辑来定义将会更好。为此,我们把“sesametech.springrecipes.s001”包复制为名叫“sesametech.springrecipes.s007”的包,然后在该包下创建“PrefixGenerator”接口来定义前缀生成操作,代码如下:
public interface PrefixGenerator {
public String getPrefix();
}
接下来,我们假定一种生成前缀的策略,即使用特殊的模式格式化系统当前日期。为此,我们创建“DatePrefixGenerator”实现类,代码如下:
public class DatePrefixGenerator implements PrefixGenerator {
private DateFormat formatter;
public void setPattern(String pattern) {
this.formatter =new SimpleDateFormat(pattern);
}
@Override
public String getPrefix() {
return formatter.format(System.currentTimeMillis());
}
}
这个实现类将通过设值方法 setPattern() 注入模式字符串,然后用于创建 java.text.DateFormat 对象以便格式化日期。
现在,我们可以用任意模式字符串来声明类型为DatePrefixGenerator 的 Bean,为此,我们在包下的beans.xml 配置文件中先配置一个 DatePrefixGenerator 的 Bean,如下所示:
<bean
id="datePrefixGenerator"
class="sesametech.springrecipes.s007.DatePrefixGenerator">
<propertyname="pattern"value="yyyyMMdd"/>
</bean>
为了应用这个前缀生成器,序列生成器 SequenceGenerator类应该接受 PrefixGenerator 类型的对象,而不是简单的前缀字符串。为此,我们可以选择通过设值方法以注入这个前缀生成器,修改后的SequenceGenerator 类代码片段如下所示:
public class SequenceGenerator {
private PrefixGeneratorprefixGenerator;
……
publicSequenceGenerator(PrefixGeneratorprefixGenerator, String suffix, int initial) {
this.prefixGenerator =prefixGenerator;
this.suffix =suffix;
this.initial =initial;
}
public voidsetPrefixGenerator(PrefixGenerator prefix) {
this.prefixGenerator =prefix;
}
public synchronized String getSequence(){
StringBufferbuffer = new StringBuffer();
buffer.append(prefixGenerator.getPrefix());
buffer.append(initial +counter++);
buffer.append(suffix);
return buffer.toString();
}
getter & setter…
}
然后,在 SequenceGenerator Bean 的配置中,可以包含一个 <ref> 标签来引用 ID 为 datePrefixGenerator 的 Bean 作为其 prefixGenerator 属性,代码片段如下所示:
<bean
id="sequenceGenerator"
class="sesametech.springrecipes.s007.SequenceGenerator">
<propertyname="initial"value="100000"/>
<propertyname="suffix"value="A"/>
<propertyname="prefixGenerator"ref="datePrefixGenerator"/>
</bean>
最后,我们修改一下测试类“SequenceGeneratorTest”的代码,如下所示:
public class SequenceGeneratorTest{
@SuppressWarnings("resource")
public static void main(String[] args) {
ApplicationContextcontext = newClassPathXmlApplicationContext("sesametech/springrecipes/s007/beans.xml");
SequenceGeneratorgenerator = (SequenceGenerator)context.getBean("sequenceGenerator");
System.out.println(generator.getSequence());
System.out.println(generator.getSequence());
}
}
此时,运行一下,如果无意外,结果看起来应该如下所示:
20160608100000A
20160608100001A
同样,你也可以通过构造方法来注入 Bean 引用,对于本示例,读者可以参考以下配置,亲自试验一下:
<bean
id="sequenceGenerator"
class="sesametech.springrecipes.s007.SequenceGenerator">
<constructor-argref="datePrefixGenerator"/>
<constructor-argvalue="B"/>
<constructor-argvalue="200000"/>
</bean>
声明内部 Bean
如果 Bean 实例只用于一个特殊的属性,可以声明为内部Bean。内部 Bean 声明直接包含在<property> 或者 <constructor-arg> 中,不设置任何 id 或者 name 属性。这样的话,这个Bean 将是匿名的,不能用于其他地方,即使你为这个内部 Bean 设置了id 或者 name 属性,也将被忽略。
对于本示例,可以配置成如下所示:
<bean
id="sequenceGenerator"
class="sesametech.springrecipes.s007.SequenceGenerator">
<propertyname="initial"value="100000"/>
<propertyname="suffix"value="A"/>
<propertyname="prefixGenerator">
<beanclass="sesametech.springrecipes.s007.DatePrefixGenerator">
<propertyname="pattern"value="yyyyMMdd"/>
</bean>
</property>
</bean>
也可以配置成如下所示:
<bean
id="sequenceGenerator"
class="sesametech.springrecipes.s007.SequenceGenerator">
<constructor-arg>
<beanclass="sesametech.springrecipes.s007.DatePrefixGenerator">
<propertyname="pattern"value="yyyyMMdd"/>
</bean>
</constructor-arg>
<constructor-argvalue="B"/>
<constructor-argvalue="200000"/>
</bean>
作为练习,请读者亲自动手试验一下。
好了,今天就写到这里,待续···
- Spring 攻略第003讲
- Spring 攻略第001讲
- Spring 攻略第002讲
- Spring 攻略第004讲
- Spring 攻略第001讲续
- (第1讲)spring的基础知识
- 《Spring攻略》 第1章 Spring简介 - IoC基础
- 《Spring攻略》 第2章 高级Spring IoC容器
- 《Spring攻略》第3章 Spring AOP和AspectJ支持
- (第2讲)spring的基本流程
- arcims 第2讲
- 第8讲 总结
- Java第2讲
- 第4讲 常用命令
- 数据结构第1讲
- 第22讲
- 第23讲
- 第24讲
- 机器学习:LDA_数学基础_1:贝叶斯数学_基础
- keytool工具命令
- Nginx 负载均衡
- MJExtension中MJTypeEncoding.m报错问题
- View的requestDisallowInterceptTouchEvent对事件的影响
- Spring 攻略第003讲
- iOS 程序中的内存分配 栈区 堆区 全局区(静态存储区)
- 容器组(Containers)
- 如何触发<z:select>值改变事件
- 实验1:Problem A: 平面上的点和线——Point类、Line类 (I)
- Converting and transferring data
- MYSQL中replace into的用法
- android Fragment里的newInstance和构造函数
- cygwin的安装