Skip to content

Commit dc1edcc

Browse files
committed
prototype beans receive independent collection/array even when based on single value (SPR-5512)
1 parent 2de9e2a commit dc1edcc

File tree

4 files changed

+63
-7
lines changed

4 files changed

+63
-7
lines changed

org.springframework.beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2008 the original author or authors.
2+
* Copyright 2002-2009 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -26,6 +26,7 @@
2626
import java.security.PrivilegedAction;
2727
import java.util.ArrayList;
2828
import java.util.Arrays;
29+
import java.util.Collection;
2930
import java.util.HashMap;
3031
import java.util.HashSet;
3132
import java.util.Iterator;
@@ -1249,7 +1250,8 @@ protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrap
12491250
}
12501251
deepCopy.add(pv);
12511252
}
1252-
else if (originalValue instanceof TypedStringValue && convertible) {
1253+
else if (originalValue instanceof TypedStringValue && convertible &&
1254+
!(convertedValue instanceof Collection || ObjectUtils.isArray(convertedValue))) {
12531255
pv.setConvertedValue(convertedValue);
12541256
deepCopy.add(pv);
12551257
}

org.springframework.beans/src/test/java/org/springframework/beans/factory/xml/UtilNamespaceHandlerTests.java

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import java.util.Properties;
2323
import java.util.Set;
2424
import java.util.TreeMap;
25+
import java.util.Arrays;
2526

2627
import junit.framework.TestCase;
2728
import test.beans.CustomEnum;
@@ -158,6 +159,37 @@ public void testNestedCollections() throws Exception {
158159
Set innerSet = (Set) map.get("foo");
159160
assertEquals(1, innerSet.size());
160161
assertTrue(innerSet.contains("bar"));
162+
163+
TestBean bean2 = (TestBean) this.beanFactory.getBean("nestedCollectionsBean");
164+
assertEquals(list, bean2.getSomeList());
165+
assertEquals(set, bean2.getSomeSet());
166+
assertEquals(map, bean2.getSomeMap());
167+
assertFalse(list == bean2.getSomeList());
168+
assertFalse(set == bean2.getSomeSet());
169+
assertFalse(map == bean2.getSomeMap());
170+
}
171+
172+
public void testNestedShortcutCollections() throws Exception {
173+
TestBean bean = (TestBean) this.beanFactory.getBean("nestedShortcutCollections");
174+
175+
assertEquals(1, bean.getStringArray().length);
176+
assertEquals("fooStr", bean.getStringArray()[0]);
177+
178+
List list = bean.getSomeList();
179+
assertEquals(1, list.size());
180+
assertEquals("foo", list.get(0));
181+
182+
Set set = bean.getSomeSet();
183+
assertEquals(1, set.size());
184+
assertTrue(set.contains("bar"));
185+
186+
TestBean bean2 = (TestBean) this.beanFactory.getBean("nestedShortcutCollections");
187+
assertTrue(Arrays.equals(bean.getStringArray(), bean2.getStringArray()));
188+
assertFalse(bean.getStringArray() == bean2.getStringArray());
189+
assertEquals(list, bean2.getSomeList());
190+
assertEquals(set, bean2.getSomeSet());
191+
assertFalse(list == bean2.getSomeList());
192+
assertFalse(set == bean2.getSomeSet());
161193
}
162194

163195
public void testNestedInCollections() throws Exception {
@@ -175,6 +207,14 @@ public void testNestedInCollections() throws Exception {
175207
Map map = bean.getSomeMap();
176208
assertEquals(1, map.size());
177209
assertEquals(CustomEnum.VALUE_1, map.get("min"));
210+
211+
TestBean bean2 = (TestBean) this.beanFactory.getBean("nestedCustomTagBean");
212+
assertEquals(list, bean2.getSomeList());
213+
assertEquals(set, bean2.getSomeSet());
214+
assertEquals(map, bean2.getSomeMap());
215+
assertFalse(list == bean2.getSomeList());
216+
assertFalse(set == bean2.getSomeSet());
217+
assertFalse(map == bean2.getSomeMap());
178218
}
179219

180220
public void testCircularCollections() throws Exception {

org.springframework.beans/src/test/resources/org/springframework/beans/factory/xml/testUtilNamespace.xml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@
6767
<value>Rob Harrop</value>
6868
</util:set>
6969

70-
<bean id="nestedCollectionsBean" class="test.beans.TestBean">
70+
<bean id="nestedCollectionsBean" class="test.beans.TestBean" scope="prototype">
7171
<property name="someList">
7272
<util:list>
7373
<value>foo</value>
@@ -89,6 +89,12 @@
8989
</property>
9090
</bean>
9191

92+
<bean id="nestedShortcutCollections" class="test.beans.TestBean" scope="prototype">
93+
<property name="stringArray" value="fooStr"/>
94+
<property name="someList" value="foo"/>
95+
<property name="someSet" value="bar"/>
96+
</bean>
97+
9298
<bean id="nestedCustomTagBean" class="test.beans.TestBean" scope="prototype">
9399
<property name="someList">
94100
<list>

org.springframework.core/src/main/java/org/springframework/util/ObjectUtils.java

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2008 the original author or authors.
2+
* Copyright 2002-2009 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -82,10 +82,18 @@ public static boolean isCompatibleWithThrowsClause(Throwable ex, Class[] declare
8282
}
8383

8484
/**
85-
* Return whether the given array is empty: that is, <code>null</code>
86-
* or of zero length.
85+
* Determine whether the given object is an array:
86+
* either an Object array or a primitive array.
87+
* @param obj the object to check
88+
*/
89+
public static boolean isArray(Object obj) {
90+
return (obj != null && obj.getClass().isArray());
91+
}
92+
93+
/**
94+
* Determine whether the given array is empty:
95+
* i.e. <code>null</code> or of zero length.
8796
* @param array the array to check
88-
* @return whether the given array is empty
8997
*/
9098
public static boolean isEmpty(Object[] array) {
9199
return (array == null || array.length == 0);

0 commit comments

Comments
 (0)