References to Other Beans (Collaborators)
對(duì)其他bean的引用(協(xié)作者)
The ref
element is the final element inside a <constructor-arg/>
or <property/>
definition element. Here, you set the value of the specified property of a bean to be a reference to another bean (a collaborator) managed by the container. The referenced bean is a dependency of the bean whose property is to be set, and it is initialized on demand as needed before the property is set. (If the collaborator is a singleton bean, it may already be initialized by the container.) All references are ultimately a reference to another object. Scoping and validation depend on whether you specify the ID or name of the other object through the bean
or parent
attribute.
ref元素是<constructor-arg/>
或 <property/>
·定義元素中的最后一個(gè)元素碧信。在這里,您將bean的指定屬性的值設(shè)置為對(duì)容器管理的另一個(gè)bean(協(xié)作者)的引用譬挚。被引用的bean是要設(shè)置其屬性的bean的依賴項(xiàng),并且在設(shè)置屬性之前根據(jù)需要對(duì)其進(jìn)行初始化。(如果collaborator
是一個(gè)單例bean,那么它可能已經(jīng)被容器初始化了碎捺。)所有引用最終都是對(duì)另一個(gè)對(duì)象的引用。作用域和驗(yàn)證取決于是否通過(guò)bean或父屬性指定另一個(gè)對(duì)象的ID或名稱。
Specifying the target bean through the bean
attribute of the <ref/>
tag is the most general form and allows creation of a reference to any bean in the same container or parent container, regardless of whether it is in the same XML file. The value of the bean
attribute may be the same as the id
attribute of the target bean or be the same as one of the values in the name
attribute of the target bean. The following example shows how to use a ref
element:
通過(guò)<ref/>
標(biāo)記的bean屬性指定目標(biāo)bean是最常見(jiàn)的形式收厨,它允許創(chuàng)建對(duì)同一容器或父容器中任何bean的引用晋柱,而不管它是否在同一個(gè)XML文件中。bean屬性的值可以與目標(biāo)bean的id屬性相同诵叁,也可以與目標(biāo)bean的name屬性中的某個(gè)值相同雁竞。以下示例顯示如何使用ref元素:
<ref bean="someBean"/>
Specifying the target bean through the parent
attribute creates a reference to a bean that is in a parent container of the current container. The value of the parent
attribute may be the same as either the id
attribute of the target bean or one of the values in the name
attribute of the target bean. The target bean must be in a parent container of the current one. You should use this bean reference variant mainly when you have a hierarchy of containers and you want to wrap an existing bean in a parent container with a proxy that has the same name as the parent bean. The following pair of listings shows how to use the parent
attribute:
通過(guò)parent
屬性指定目標(biāo)bean
將創(chuàng)建對(duì)當(dāng)前容器的父容器中的bean的引用。父屬性的值可以與目標(biāo)bean的id屬性或目標(biāo)bean的name屬性中的某個(gè)值相同黎休。目標(biāo)bean必須位于當(dāng)前bean的父容器中浓领。您應(yīng)該使用這個(gè)bean引用變量,主要是當(dāng)您有一個(gè)容器的層次結(jié)構(gòu)势腮,并且您想用一個(gè)與父bean同名的代理將現(xiàn)有的bean包裝在父容器中联贩。以下兩個(gè)列表顯示了如何使用parent屬性:
<!-- in the parent context -->
<bean id="accountService" class="com.something.SimpleAccountService">
<!-- insert dependencies as required as here -->
</bean>
<!-- in the child (descendant) context -->
<bean id="accountService" <!-- bean name is the same as the parent bean -->
class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="target">
<ref parent="accountService"/> <!-- notice how we refer to the parent bean -->
</property>
<!-- insert other configuration and dependencies as required here -->
</bean>
The local attribute on the ref element is no longer supported in the 4.0 beans XSD, since it does not provide value over a regular bean reference any more. Change your existing ref local references to ref bean when upgrading to the 4.0 schema. |
|
---|---|
4.0beans xsd不再支持ref元素上的local屬性,因?yàn)樗辉偬峁┏R?guī)bean引用的值捎拯。在升級(jí)到4.0模式時(shí)泪幌,將現(xiàn)有的ref本地引用更改為ref bean。 |
Inner Beans
A <bean/>
element inside the <property/>
or <constructor-arg/>
elements defines an inner bean, as the following example shows:
<bean id="outer" class="...">
<!-- instead of using a reference to a target bean, simply define the target bean inline -->
<property name="target">
<bean class="com.example.Person"> <!-- this is the inner bean -->
<property name="name" value="Fiona Apple"/>
<property name="age" value="25"/>
</bean>
</property>
</bean>
An inner bean definition does not require a defined ID or name. If specified, the container does not use such a value as an identifier. The container also ignores the scope
flag on creation, because inner beans are always anonymous and are always created with the outer bean. It is not possible to access inner beans independently or to inject them into collaborating beans other than into the enclosing bean.
內(nèi)部bean定義不需要定義的ID或名稱署照。如果指定祸泪,則容器不使用此值作為標(biāo)識(shí)符。容器在創(chuàng)建時(shí)也會(huì)忽略范圍標(biāo)志建芙,因?yàn)閮?nèi)部bean總是匿名的没隘,并且總是與外部bean一起創(chuàng)建。不可能獨(dú)立地訪問(wèn)內(nèi)部bean禁荸,也不可能將它們注入到除封閉bean之外的協(xié)作bean中右蒲。
As a corner case, it is possible to receive destruction callbacks from a custom scope?—?for example, for a request-scoped inner bean contained within a singleton bean. The creation of the inner bean instance is tied to its containing bean, but destruction callbacks let it participate in the request scope’s lifecycle. This is not a common scenario. Inner beans typically simply share their containing bean’s scope.
例如,從一個(gè)單獨(dú)的bean到一個(gè)單獨(dú)的bean的作用域赶熟,比如一個(gè)調(diào)用bean瑰妄。內(nèi)部bean實(shí)例的創(chuàng)建與其包含的bean相關(guān)聯(lián),但是銷毀回調(diào)允許它參與請(qǐng)求范圍的生命周期映砖。這種情況并不常見(jiàn)间坐。內(nèi)部bean通常只共享它們的包含bean的范圍。
Collections
The <list/>
, <set/>
, <map/>
, and <props/>
elements set the properties and arguments of the Java Collection
types List
, Set
, Map
, and Properties
, respectively. The following example shows how to use them:
<list/>邑退、<set/>踏施、<map/>和<props/>元素分別設(shè)置Java集合類型list帽蝶、set、map和properties的屬性和參數(shù)。下面的示例演示如何使用它們:
<bean id="moreComplexObject" class="example.ComplexObject">
<!-- results in a setAdminEmails(java.util.Properties) call -->
<property name="adminEmails">
<props>
<prop key="administrator">administrator@example.org</prop>
<prop key="support">support@example.org</prop>
<prop key="development">development@example.org</prop>
</props>
</property>
<!-- results in a setSomeList(java.util.List) call -->
<property name="someList">
<list>
<value>a list element followed by a reference</value>
<ref bean="myDataSource" />
</list>
</property>
<!-- results in a setSomeMap(java.util.Map) call -->
<property name="someMap">
<map>
<entry key="an entry" value="just some string"/>
<entry key ="a ref" value-ref="myDataSource"/>
</map>
</property>
<!-- results in a setSomeSet(java.util.Set) call -->
<property name="someSet">
<set>
<value>just some string</value>
<ref bean="myDataSource" />
</set>
</property>
</bean>
The value of a map key or value, or a set value, can also be any of the following elements:
映射鍵或值的值耘纱,或設(shè)置值巾陕,也可以是以下任何元素:
bean | ref | idref | list | set | map | props | value | null
Collection Merging
集合合并
The Spring container also supports merging collections. An application developer can define a parent <list/>, <map/>, <set/> or <props/> element and have child <list/>, <map/>, <set/> or <props/> elements inherit and override values from the parent collection. That is, the child collection’s values are the result of merging the elements of the parent and child collections, with the child’s collection elements overriding values specified in the parent collection.
Spring容器還支持合并集合踢匣。應(yīng)用程序開(kāi)發(fā)人員可以定義父元素<list/>似枕、<map/>溯警、<set/>或<props/>元素,并讓子元素<list/>狡相、<map/>梯轻、<set/>或<props/>繼承并重寫父集合中的值。也就是說(shuō)尽棕,子集合的值是合并父集合和子集合的元素的結(jié)果喳挑,子集合元素覆蓋父集合中指定的值。
This section on merging discusses the parent-child bean mechanism. Readers unfamiliar with parent and child bean definitions may wish to read the relevant section before continuing.
關(guān)于合并的這一節(jié)討論了父子bean機(jī)制滔悉。不熟悉父bean和子bean定義的讀者可能希望在繼續(xù)之前閱讀相關(guān)部分伊诵。
The following example demonstrates collection merging:
以下示例演示集合合并:
<beans>
<bean id="parent" abstract="true" class="example.ComplexObject">
<property name="adminEmails">
<props>
<prop key="administrator">administrator@example.com</prop>
<prop key="support">support@example.com</prop>
</props>
</property>
</bean>
<bean id="child" parent="parent">
<property name="adminEmails">
<!-- the merge is specified on the child collection definition -->
<props merge="true">
<prop key="sales">sales@example.com</prop>
<prop key="support">support@example.co.uk</prop>
</props>
</property>
</bean>
<beans>
Notice the use of the merge=true
attribute on the <props/>
element of the adminEmails
property of the child
bean definition. When the child
bean is resolved and instantiated by the container, the resulting instance has an adminEmails
Properties
collection that contains the result of merging the child’s adminEmails
collection with the parent’s adminEmails
collection. The following listing shows the result:
注意在子bean定義的adminEmails屬性的<props/>元素上使用了merge=true屬性。當(dāng)容器解析并實(shí)例化子bean時(shí)回官,生成的實(shí)例具有一個(gè)adminEmails Properties集合曹宴,該集合包含將子級(jí)的adminEmails集合與父級(jí)的adminEmails集合合并的結(jié)果。下面的列表顯示了結(jié)果:
administrator=administrator@example.com
sales=sales@example.com
support=support@example.co.uk
The child Properties
collection’s value set inherits all property elements from the parent <props/>
, and the child’s value for the support
value overrides the value in the parent collection.
子Properties集合的值集繼承父集合<props/>中的所有屬性元素歉提,子級(jí)的支持值的值覆蓋父集合中的值笛坦。
This merging behavior applies similarly to the <list/>
, <map/>
, and <set/>
collection types. In the specific case of the <list/>
element, the semantics associated with the List
collection type (that is, the notion of an ordered
collection of values) is maintained. The parent’s values precede all of the child list’s values. In the case of the Map
, Set
, and Properties
collection types, no ordering exists. Hence, no ordering semantics are in effect for the collection types that underlie the associated Map
, Set
, and Properties
implementation types that the container uses internally.
此合并行為類似于<list/>、<map/>和<set/>集合類型苔巨。在<list/>元素的特定情況下版扩,與list collection類型相關(guān)聯(lián)的語(yǔ)義(即值的有序集合的概念)被維護(hù)。父項(xiàng)的值先于所有子項(xiàng)列表的值侄泽。對(duì)于Map礁芦、Set和Properties集合類型,不存在排序悼尾。因此柿扣,對(duì)于容器內(nèi)部使用的關(guān)聯(lián)映射、集和屬性實(shí)現(xiàn)類型的集合類型诀豁,沒(méi)有有效的排序語(yǔ)義窄刘。
Limitations of Collection Merging
集合合并的局限性
You cannot merge different collection types (such as a Map
and a List
). If you do attempt to do so, an appropriate Exception
is thrown. The merge
attribute must be specified on the lower, inherited, child definition. Specifying the merge
attribute on a parent collection definition is redundant and does not result in the desired merging.
不能合并不同的集合類型(如映射和列表)窥妇。如果您確實(shí)嘗試這樣做舷胜,則會(huì)引發(fā)適當(dāng)?shù)漠惓!1仨氃谳^低的繼承子定義上指定merge屬性活翩。在父集合定義上指定merge屬性是多余的烹骨,不會(huì)導(dǎo)致所需的合并。
Strongly-typed collection
強(qiáng)類型集合
With the introduction of generic types in Java 5, you can use strongly typed collections. That is, it is possible to declare a Collection
type such that it can only contain (for example) String
elements. If you use Spring to dependency-inject a strongly-typed Collection
into a bean, you can take advantage of Spring’s type-conversion support such that the elements of your strongly-typed Collection
instances are converted to the appropriate type prior to being added to the Collection
. The following Java class and bean definition show how to do so:
隨著Java5中泛型類型的引入材泄,您可以使用強(qiáng)類型集合沮焕。也就是說(shuō),可以聲明一個(gè)集合類型拉宗,使其只能包含(例如)字符串元素峦树。如果使用Spring將強(qiáng)類型集合注入bean中辣辫,那么可以利用Spring的類型轉(zhuǎn)換支持,以便在將強(qiáng)類型集合實(shí)例的元素添加到集合之前將其轉(zhuǎn)換為適當(dāng)?shù)念愋涂O旅娴腏ava類的定義如下:
Java
public class SomeClass {
private Map<String, Float> accounts;
public void setAccounts(Map<String, Float> accounts) {
this.accounts = accounts;
}
}
<beans>
<bean id="something" class="x.y.SomeClass">
<property name="accounts">
<map>
<entry key="one" value="9.99"/>
<entry key="two" value="2.75"/>
<entry key="six" value="3.99"/>
</map>
</property>
</bean>
</beans>
When the accounts
property of the something
bean is prepared for injection, the generics information about the element type of the strongly-typed Map<String, Float>
is available by reflection. Thus, Spring’s type conversion infrastructure recognizes the various value elements as being of type Float
, and the string values (9.99, 2.75
, and 3.99
) are converted into an actual Float
type.
當(dāng)something bean的accounts屬性準(zhǔn)備好注入時(shí)急灭,關(guān)于強(qiáng)類型Map<String,F(xiàn)loat>的元素類型的泛型信息可以通過(guò)反射獲得谷遂。因此葬馋,Spring的類型轉(zhuǎn)換基礎(chǔ)設(shè)施將各種值元素識(shí)別為Float類型,字符串值(9.99肾扰、2.75和3.99)轉(zhuǎn)換為實(shí)際的Float類型畴嘶。