util:list如何使用scope =“prototype”?

时间:2014-04-03 06:28:21

标签: java spring

如果我使用以下Spring XML配置,如果将结果bean分配给多个属性,结果会是什么?

<util:list id="myBeanId" scope="prototype">
  <bean class="com.mypackage.MyTestBeanClass1" />
  <bean class="com.mypackage.MyTestBeanClass2" />
</util:list>

据我所知,有两种可能的结果:

  • 创建了多个列表,但其中的bean是共享的(因为它们的作用域默认为单例)
  • 创建多个列表,并为每个列表实例创建每个bean的新副本

此外,这种情况怎么样?

<bean id="referencedBean" class="com.mypackage.MyTestBeanClass1" />
<util:list id="myBeanId" scope="prototype">
  <ref bean="referencedBean" />
  <bean class="com.mypackage.MyTestBeanClass2" />
</util:list>

这似乎提供了更多的可能性:

  • referencedBean仍为单身,但会创建多个MyTestBeanClass2个实例。
  • referencedBeanMyTestBeanClass2对于每个创建的列表实例都是重复的(这让我觉得不太可能,但仍然看似合理。)

我似乎无法在春季文档中找到对此的任何讨论。事实上,据我所知,util:list中scope属性的存在甚至在文档中都没有提到。我错过了,还是完全没有记录?如果可以/我应该依赖任何特定行为吗?

1 个答案:

答案 0 :(得分:5)

Bean scopes的spring文档介绍了一种很好的方法:

  

创建bean定义时,可以创建一个配方,用于创建该bean定义定义的类的实际实例。 bean定义是一个配方的想法很重要,因为这意味着,与一个类一样,您可以从一个配方创建许多对象实例。

因此,无论您使用<bean>还是<util:list>定义bean,您仍然只是创建一个可重用的配方。 scope属性确定配方是否实际重复使用。

示例

在这个示例上下文中,我定义了两个配方:

  • singleBean使用默认的单一作用域
  • aList原型范围

<bean id="singleBean" class="org.example.SingleBean" />

<util:list id="aList" scope="prototype">
    <value>some string value</value>
    <bean class="org.example.TestBean" />
    <ref bean="singleBean" />
</util:list>

现在我运行这个测试应用程序:

List<?> list = context.getBean("aList", List.class);
List<?> list2 = context.getBean("aList", List.class);

System.out.println(list);
System.out.println(list2);
System.out.println(list == list2);

由于aList是原型,每次我要求它弹簧再次运行配方。

  • TestBean是列表配方的一部分,因此每次都会创建一个新的TestBean
  • <ref>是对具有单独范围值的另一个食谱的引用。第一次创建aList时,将遵循singleBean的配方,并将结果缓存在上下文中(因为它的范围是单例)。随后运行aList配方将导致查找相同的singleBean值。

程序的输出如下:

[some string value, org.example.TestBean@195198e8, org.example.SingleBean@3c0db454]
[some string value, org.example.TestBean@27ba1599, org.example.SingleBean@3c0db454]
false

两个不同的列表,包含两个不同的TestBeans,但只有一个SingleBean。

基本上,util:list并不特别。如果您创建了一个具有3个属性的类,并在上面的示例中使用它而不是util:list,则结果将是相同的。