《Spring攻略(第2版)》——1.5 指定Bean引用
本節書摘來自異步社區《Spring攻略(第2版)》一書中的第1章,第1.5節,作者: 【美】Gary Mak , Josh Long , Daniel Rubio著,更多章節內容可以訪問雲棲社區“異步社區”公眾號查看
1.5 指定Bean引用
1.5.1 問題
組成應用程序的Bean往往需要互相協作完成應用功能。為了Bean之間的相互訪問,你必須在Bean配置文件中指定Bean引用。
1.5.2 解決方案
在Bean配置文件中,你可以用元素為Bean屬性或者構造程序參數指定Bean引用。隻需要用元素指定一個簡單值就可以輕鬆完成這一工作。你也可以像內部Bean一樣直接地在屬性或者構造程序中包含一個Bean聲明。
1.5.3 工作原理
在你的序列生成器中接受字符串值作為前綴的靈活性不足以滿足將來的要求。如果前綴生成可以由某種編程邏輯自定義將會更好。你可以創建PrefixGenerator接口來定義前綴生成操作。
package com.apress.springrecipes.sequence;
public interface PrefixGenerator {
public String getPrefix();
}
使用特殊的模式格式化當前係統日期是一種前綴生成策略。讓我們創建實現PrefixGenerator接口的DatePrefixGenerator類。
package com.apress.springrecipes.sequence;
...
public class DatePrefixGenerator implements PrefixGenerator {
private DateFormat formatter;
public void setPattern(String pattern) {
this.formatter = new SimpleDateFormat(pattern);
}
public String getPrefix() {
return formatter.format(new Date());
}
}
這個生成器的模式將通過設值方法setPattern()注入,然後用於創建java.text.DateFormat對象格式化日期。由於模式字符串在DateFormat對象創建之後不再使用,所以沒有必要將它存入一個私有字段中。
現在你可以用任意模式字符串聲明類型為DatePrefixGenerator的Bean來格式化日期。
<bean
>
<property name="pattern" value="yyyyMMdd" />
</bean>
為設值方法指定Bean引用
為了應用這個前綴生成器方法,SequenceGenerator類應該接受PrefixGenerator類型的對象而不是簡單的前綴字符串。你可以選擇設置方法注入來接受這個前綴生成器。你必須刪除可能導致編譯錯誤的prefix屬性,以及設值方法和構造程序。
package com.apress.springrecipes.sequence;
public class SequenceGenerator {
...
private PrefixGenerator prefixGenerator;
public void setPrefixGenerator(PrefixGenerator prefixGenerator) {
this.prefixGenerator = prefixGenerator;
}
public synchronized String getSequence() {
StringBuffer buffer = new StringBuffer();
buffer.append(prefixGenerator.getPrefix());
buffer.append(initial + counter++);
buffer.append(suffix);
return buffer.toString();
}
}
然後,SequenceGenerator bean可以包含一個元素,引用datePrefixGenerator bean作為其prefixGenerator屬性。
<bean
>
<property name="initial" value="100000" />
<property name="suffix" value="A" />
<property name="prefixGenerator">
<ref bean="datePrefixGenerator" />
</property>
</bean>
元素的bean屬性中的Bean名稱可以是對IoC容器中的任何Bean的引用,即使這個Bean不在同一個XML配置文件中定義。如果你引用相同XML文件中的一個Bean,應該使用local屬性,因為這是一個XML ID引用。你的XML編輯器將幫助你校驗Bean ID是否存在於相同的XML文件中(也就是引用完整性)。
<bean
>
...
<property name="prefixGenerator">
<ref local="datePrefixGenerator" />
</property>
</bean>
還有一個在元素的ref屬性中指定Bean引用的方便簡寫。
<bean
>
...
<property name="prefixGenerator" ref="datePrefixGenerator" />
</bean>
但是這樣一來,你的XML編輯器將不能校驗引用完整性。實際上,這跟指定元素的bean屬性效果相同。
Spring 2.x提供另一個便利的簡寫來指定Bean引用,使用pschema將bean引用作為元素的一個屬性。這可以縮短XML配置行。
<beans xmlns="https://www.springframework.org/schema/beans"
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xmlns:p="https://www.springframework.org/schema/p"
xsi:schemaLocation="https://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean
p:suffix="A" p:initial="1000000"
p:prefixGenerator-ref="datePrefixGenerator" />
</beans>
為了區分Bean引用與簡單的屬性值,你必須在屬性名後麵加上-ref後綴。
為構造程序參數指定Bean引用
Bean引用也可以應用到構造程序注入。例如,你可以添加一個接受PrefixGenerator對象參數的構造程序。
package com.apress.springrecipes.sequence;
public class SequenceGenerator {
...
private PrefixGenerator prefixGenerator;
public SequenceGenerator(PrefixGenerator prefixGenerator) {
this.prefixGenerator = prefixGenerator;
}
}
在元素中,你可以用像在元素中一樣包含一個Bean引用。
<bean
>
<constructor-arg>
<ref local="datePrefixGenerator" />
</constructor-arg>
<property name="initial" value="100000" />
<property name="suffix" value="A" />
</bean>
指定Bean引用的簡寫也適用於。
<bean
>
<constructor-arg ref="datePrefixGenerator" />
...
</bean>
聲明內部Bean
如果Bean實例隻用於一個特殊的屬性,可以聲明為內部Bean。內部Bean聲明直接包含在或中,不設置任何id或者name屬性。這樣,這個Bean將是匿名的,無法在別處使用。實際上,即使為內部Bean定義id或者name屬性,也將被忽略。
<bean
>
<property name="initial" value="100000" />
<property name="suffix" value="A" /
<property name="prefixGenerator">
<bean >
<property name="pattern" value="yyyyMMdd" />
</bean>
</property>
</bean>
內部Bean也可以在構造程序參數中聲明。
<bean
>
<constructor-arg>
<bean >
<property name="pattern" value="yyyyMMdd" />
</bean>
</constructor-arg>
<property name="initial" value="100000" />
<property name="suffix" value="A" />
</bean>
最後更新:2017-05-31 15:01:40