util:list如何使用scope ="prototype"?

Jul*_*les 7 java spring

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

<util:list id="myBeanId" scope="prototype">
  <bean class="com.mypackage.MyTestBeanClass1" />
  <bean class="com.mypackage.MyTestBeanClass2" />
</util:list>
Run Code Online (Sandbox Code Playgroud)

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

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

那么,这个场景怎么样?

<bean id="referencedBean" class="com.mypackage.MyTestBeanClass1" />
<util:list id="myBeanId" scope="prototype">
  <ref bean="referencedBean" />
  <bean class="com.mypackage.MyTestBeanClass2" />
</util:list>
Run Code Online (Sandbox Code Playgroud)

这似乎提供了额外的可能性:

  • referencedBean仍然单身,但多个实例MyTestBeanClass2被创建.
  • 这两个referencedBeanMyTestBeanClass2被复制的创建的列表中的每个实例(这在我看来是不太可能的,但仍然可行).

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

tak*_*eek 5

Bean作用域的spring文档描述了一种查看它的好方法:

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

因此,无论您使用<bean>或定义bean <util:list>,您仍然只是创建一个可重用的配方.该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>
Run Code Online (Sandbox Code Playgroud)

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

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);
Run Code Online (Sandbox Code Playgroud)

既然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
Run Code Online (Sandbox Code Playgroud)

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

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