组成应用程序的Bean往往旭阳互相协作完成应用功能。为了Bean之间的相互访问,你必须在Bean配置文件中指定Bean引用,可以使用<ref>元素为Bean属性或者构造程序参数指定Bean引用。可以像内部Bean一样,直接在属性或者构造程序中包含一个Bean声明。
(1)PrefixGenerator接口
/* * Copyright 2013-2015 */ package com.jackie.codeproject.springrecipesnote.springioc; /** * Title: PrefixGenerator.java * 生成前缀 * * @author jackie * @since Apr 18, 2013 9:54:43 PM * @version V1.0 */ public interface PrefixGenerator { public String getPrefix(); }
(2)日期前缀生成器DatePrefixGenerator
/* * Copyright 2013-2015 */ package com.jackie.codeproject.springrecipesnote.springioc; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; /** * Title: DatePrefixGenerator.java * 日期前缀 * * @author jackie * @since Apr 18, 2013 10:03:02 PM * @version V1.0 */ 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(new Date()); } }
(3)序列生成器SequenceGenerator
/* * 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 prefixGenerator : 前缀生成器 */ private PrefixGenerator prefixGenerator; /** * @Fields suffix : 后缀 */ private String suffix; /** * @Fields initial : 初始值 */ private int initial; /** * @Fields counter : 计数器 */ private int counter; public SequenceGenerator() { } public SequenceGenerator(PrefixGenerator prefixGenerator){ this.prefixGenerator = prefixGenerator; } /** * 获取序列号,声明为同步,使其成为线程安全的方法 * @author jackie * @date Apr 13, 2013 * @return * @return String */ public synchronized String getSquence() { StringBuffer buffer = new StringBuffer(); buffer.append(prefixGenerator.getPrefix()); buffer.append(initial + counter++); buffer.append(suffix); return buffer.toString(); } /** * <p>Title: </p> * <p>Description: </p> * @param suffix * @param initial */ public SequenceGenerator(int initial, String suffix) { this.suffix = suffix; this.initial = initial; } /** * @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; } /** * @param prefixGenerator the prefixGenerator to set */ public void setPrefixGenerator(PrefixGenerator prefixGenerator) { this.prefixGenerator = prefixGenerator; } }
(4)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="datePrefixGenerator" class="com.jackie.codeproject.springrecipesnote.springioc.DatePrefixGenerator"> <property name="pattern" value="yyyyMMdd" /> </bean> <bean id="sequenceGenerator" class="com.jackie.codeproject.springrecipesnote.springioc.SequenceGenerator"> <constructor-arg name="initial" value="100000" /> <constructor-arg name="suffix" value="A" /> <property name="prefixGenerator"> <ref bean="datePrefixGenerator" /> </property> </bean> </beans>
<ref>元素的bean属性中的Bean名称可以是对IoC容器中任何Bean的引用,即使这个Bean不在同一个XML配置文件中定义。如果你引用相同XML文件中的一个Bean,应该使用local属性,因为这是一个bean ID引用。Spring容器会帮助你校验Bean ID是否存在于相同的XML文件中(即引用完整性)。
<bean id="datePrefixGenerator" class="com.jackie.codeproject.springrecipesnote.springioc.DatePrefixGenerator">
<property name="pattern" value="yyyyMMdd" />
</bean>
<bean id="sequenceGenerator" class="com.jackie.codeproject.springrecipesnote.springioc.SequenceGenerator">
<constructor-arg name="initial" value="100000" />
<constructor-arg name="suffix" value="A" />
<property name="prefixGenerator">
<ref local="datePrefixGenerator" />
</property>
</bean>
也可以在<property>元素的ref属性中指定Bean引用。不过Spring容器不会校验引用完整性
<bean id="datePrefixGenerator" class="com.jackie.codeproject.springrecipesnote.springioc.DatePrefixGenerator">
<property name="pattern" value="yyyyMMdd" />
</bean>
<bean id="sequenceGenerator" class="com.jackie.codeproject.springrecipesnote.springioc.SequenceGenerator">
<constructor-arg name="initial" value="100000" />
<constructor-arg name="suffix" value="A" />
<property name="prefixGenerator" ref="datePrefixGenerator" />
</bean>
可以使用p schema将bean引用作为<bean>元素的一个属性。
<bean id="datePrefixGenerator" class="com.jackie.codeproject.springrecipesnote.springioc.DatePrefixGenerator"> <property name="pattern" value="yyyyMMdd" /> </bean> <bean id="sequenceGenerator" class="com.jackie.codeproject.springrecipesnote.springioc.SequenceGenerator" p:suffix="A" p:initial="100000" p:prefixGenerator-ref="datePrefixGenerator" />
为了区分Bean引用与简单属性值,必须在属性名后面加上-ref后缀。
Bean引用也可以应用到构造程序注入。
...... private PrefixGenerator prefixGenerator; public SequenceGenerator(PrefixGenerator prefixGenerator){ this.prefixGenerator = prefixGenerator;}
在<constructor-arg>元素中,可以用<ref>像在<property>元素中一样包含一个Bean引用。
<bean id="sequenceGenerator" class="com.jackie.codeproject.springrecipesnote.springioc.SequenceGenerator">
<constructor-arg>
<ref local="datePrefixGenerator" />
</constructor-arg>
<property name="initial" value="100000" />
<property name="suffix" value="A" />
</bean>
简写形式
<bean id="sequenceGenerator" class="com.jackie.codeproject.springrecipesnote.springioc.SequenceGenerator">
<constructor-arg ref="datePrefixGenerator" />
<property name="initial" value="100000" />
<property name="suffix" value="A" />
</bean>
声明内部Bean:如果Bean实例只用于一个特殊的属性,可以声明为内部Bean。内部Bean声明直接包含在<property>和<constructor-arg>中,不设置任何id或者name属性。这样,这个Bean将是匿名的,无法在别处使用。实际上,即使为内部Bean定义id或者name属性,也将被忽略。
<bean id="sequenceGenerator" class="com.jackie.codeproject.springrecipesnote.springioc.SequenceGenerator">
<property name="initial" value="100000" />
<property name="suffix" value="A" />
<property name="prefixGenerator">
<bean class="com.jackie.codeproject.springrecipesnote.springioc.DatePrefixGenerator">
<property name="pattern" value="yyyyMMdd" />
</bean>
</property>
</bean>
内部Bean也可以在构造程序参数中声明。
<bean id="sequenceGenerator" class="com.jackie.codeproject.springrecipesnote.springioc.SequenceGenerator"> <property name="initial" value="100000" /> <property name="suffix" value="A" /> <constructor-arg> <bean class="com.jackie.codeproject.springrecipesnote.springioc.DatePrefixGenerator"> <property name="pattern" value="yyyyMMdd" /> </bean> </constructor-arg> </bean>