Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does util:list behave with scope="prototype"?

Tags:

java

spring

If I use the following Spring XML config, what will be the result if I assign the resulting bean to multiple properties?

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

As far as I can see, there are two possible outcomes:

  • Multiple lists are created, but the beans inside them are shared (because their scope defaults to singleton)
  • Multiple lists are created, and a new copy of each bean is created for each list instance

Also, what about this scenario?

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

This seems to offer additional possibilities:

  • The referencedBean remains a singleton, but multiple instances of MyTestBeanClass2 are created.
  • Both referencedBean and MyTestBeanClass2 are duplicated for each instance of the list created (this strikes me as unlikely, but still plausible).

I don't seem to be able to find any discussion of this in the spring docs. In fact, as far as I can see, the existence of the scope property on util:list isn't even mentioned in the docs. Have I missed it, or is this entirely undocumented? If so can/should I rely on any particular behaviour?

like image 944
Jules Avatar asked Apr 03 '14 06:04

Jules


People also ask

How does a Spring prototype scope work?

Prototype Scope:If the scope is declared prototype, then spring IOC container will create a new instance of that bean every time a request is made for that specific bean. A request can be made to the bean instance either programmatically using getBean() method or by XML for Dependency Injection of secondary type.

How would you define prototype scope in Spring using annotation?

When a spring bean is scoped as a prototype, the Spring IoC container creates new bean instance every time when a request is made for that bean. We can define the scope of a bean as prototype using scope="prototype" attribute of element or using @Scope(value = ConfigurableBeanFactory. SCOPE_PROTOTYPE) annotation.

What is the difference between singleton and prototype scope in Spring?

Singleton: means single bean definition to a single object instance per Spring IOC container. Prototype: means a single bean definition to any number of object instances.

What is the difference between prototype and request scope in Spring?

Prototype scope creates a new instance every time getBean method is invoked on the ApplicationContext. Whereas for request scope, only one instance is created for an HttpRequest.


1 Answers

The spring documentation for Bean scopes describes a good way of looking at it:

When you create a bean definition, you create a recipe for creating actual instances of the class defined by that bean definition. The idea that a bean definition is a recipe is important, because it means that, as with a class, you can create many object instances from a single recipe.

So, whether you define a bean with <bean> or <util:list>, you are still just creating a reusable recipe. The scope attribute determines whether the recipe is actually reused.

Example

In this example context I define two recipes:

  • singleBean with the default singleton scope
  • aList with prototype scope

<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>

Now I run this test application:

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);

Since aList is prototype, every time I ask for it spring runs the recipe again.

  • TestBean is part of the recipe for the list so a new TestBean will be created each time.
  • <ref> is a reference to another recipe with a separate scope value. The first time aList is created, the recipe for singleBean will be followed and the result will be cached in the context (since it's scope singleton). Subsequent runs of the aList recipe will cause the same singleBean value to be looked up.

The output of the program looks like this:

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

Two different lists with two different TestBeans but only one SingleBean.

Basically, util:list is nothing special. If you made a class with 3 properties and used it instead of util:list in the above example, the result would be the same.

like image 108
takteek Avatar answered Oct 16 '22 12:10

takteek