Skip to content

Commit e6ce2a3

Browse files
committed
Expose autoGrowCollectionLimit in ConfigurablePropertyAccessor interface
See gh-36862
1 parent 481a574 commit e6ce2a3

5 files changed

Lines changed: 36 additions & 26 deletions

File tree

spring-beans/src/main/java/org/springframework/beans/AbstractNestablePropertyAccessor.java

Lines changed: 4 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,6 @@ public abstract class AbstractNestablePropertyAccessor extends AbstractPropertyA
7676
*/
7777
private static final Log logger = LogFactory.getLog(AbstractNestablePropertyAccessor.class);
7878

79-
private int autoGrowCollectionLimit = Integer.MAX_VALUE;
80-
8179
@Nullable Object wrappedObject;
8280

8381
private String nestedPath = "";
@@ -156,21 +154,6 @@ protected AbstractNestablePropertyAccessor(Object object, String nestedPath, Abs
156154
}
157155

158156

159-
/**
160-
* Specify a limit for array and collection auto-growing.
161-
* <p>Default is unlimited on a plain accessor.
162-
*/
163-
public void setAutoGrowCollectionLimit(int autoGrowCollectionLimit) {
164-
this.autoGrowCollectionLimit = autoGrowCollectionLimit;
165-
}
166-
167-
/**
168-
* Return the limit for array and collection auto-growing.
169-
*/
170-
public int getAutoGrowCollectionLimit() {
171-
return this.autoGrowCollectionLimit;
172-
}
173-
174157
/**
175158
* Switch the target object, replacing the cached introspection results only
176159
* if the class of the new object is different to that of the replaced object.
@@ -298,7 +281,7 @@ private void processKeyedProperty(PropertyTokenHolder tokens, PropertyValue pv)
298281
Object convertedValue = convertIfNecessary(tokens.canonicalName, oldValue, pv.getValue(),
299282
componentType, ph.nested(tokens.keys.length));
300283
int length = Array.getLength(propValue);
301-
if (arrayIndex >= length && arrayIndex < this.autoGrowCollectionLimit) {
284+
if (arrayIndex >= length && arrayIndex < getAutoGrowCollectionLimit()) {
302285
Object newArray = Array.newInstance(componentType, arrayIndex + 1);
303286
System.arraycopy(propValue, 0, newArray, 0, length);
304287
int lastKeyIndex = tokens.canonicalName.lastIndexOf('[');
@@ -324,7 +307,7 @@ else if (propValue instanceof List list) {
324307
Object convertedValue = convertIfNecessary(tokens.canonicalName, oldValue, pv.getValue(),
325308
requiredType.getResolvableType().resolve(), requiredType);
326309
int size = list.size();
327-
if (index >= size && index < this.autoGrowCollectionLimit) {
310+
if (index >= size && index < getAutoGrowCollectionLimit()) {
328311
for (int i = size; i < index; i++) {
329312
try {
330313
list.add(null);
@@ -761,7 +744,7 @@ private Object growArrayIfNecessary(Object array, int index, String name) {
761744
return array;
762745
}
763746
int length = Array.getLength(array);
764-
if (index >= length && index < this.autoGrowCollectionLimit) {
747+
if (index >= length && index < getAutoGrowCollectionLimit()) {
765748
Class<?> componentType = array.getClass().componentType();
766749
Object newArray = Array.newInstance(componentType, index + 1);
767750
System.arraycopy(array, 0, newArray, 0, length);
@@ -785,7 +768,7 @@ private void growCollectionIfNecessary(Collection<Object> collection, int index,
785768
return;
786769
}
787770
int size = collection.size();
788-
if (index >= size && index < this.autoGrowCollectionLimit) {
771+
if (index >= size && index < getAutoGrowCollectionLimit()) {
789772
Class<?> elementType = ph.getResolvableType().getNested(nestingLevel).asCollection().resolveGeneric();
790773
if (elementType != null) {
791774
for (int i = collection.size(); i < index + 1; i++) {

spring-beans/src/main/java/org/springframework/beans/AbstractPropertyAccessor.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ public abstract class AbstractPropertyAccessor extends TypeConverterSupport impl
4040

4141
private boolean autoGrowNestedPaths = false;
4242

43+
private int autoGrowCollectionLimit = Integer.MAX_VALUE;
44+
4345
boolean suppressNotWritablePropertyException = false;
4446

4547

@@ -63,6 +65,16 @@ public boolean isAutoGrowNestedPaths() {
6365
return this.autoGrowNestedPaths;
6466
}
6567

68+
@Override
69+
public void setAutoGrowCollectionLimit(int autoGrowCollectionLimit) {
70+
this.autoGrowCollectionLimit = autoGrowCollectionLimit;
71+
}
72+
73+
@Override
74+
public int getAutoGrowCollectionLimit() {
75+
return this.autoGrowCollectionLimit;
76+
}
77+
6678

6779
@Override
6880
public void setPropertyValue(PropertyValue pv) throws BeansException {

spring-beans/src/main/java/org/springframework/beans/ConfigurablePropertyAccessor.java

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,13 +63,28 @@ public interface ConfigurablePropertyAccessor extends PropertyAccessor, Property
6363
* <p>If {@code true}, a {@code null} path location will be populated
6464
* with a default object value and traversed instead of resulting in a
6565
* {@link NullValueInNestedPathException}.
66-
* <p>Default is {@code false} on a plain PropertyAccessor instance.
66+
* <p>Default is {@code false} on a plain accessor.
67+
* @since 4.1
6768
*/
6869
void setAutoGrowNestedPaths(boolean autoGrowNestedPaths);
6970

7071
/**
7172
* Return whether "auto-growing" of nested paths has been activated.
73+
* @since 4.1
7274
*/
7375
boolean isAutoGrowNestedPaths();
7476

77+
/**
78+
* Specify a limit for array and collection auto-growing.
79+
* <p>Default is unlimited on a plain accessor.
80+
* @since 7.1
81+
*/
82+
void setAutoGrowCollectionLimit(int autoGrowCollectionLimit);
83+
84+
/**
85+
* Return the limit for array and collection auto-growing.
86+
* @since 7.1
87+
*/
88+
int getAutoGrowCollectionLimit();
89+
7590
}

spring-context/src/main/java/org/springframework/validation/DataBinder.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -273,8 +273,9 @@ public boolean isAutoGrowNestedPaths() {
273273
* Specify the limit for array and collection auto-growing.
274274
* <p>Default is 256, preventing OutOfMemoryErrors in case of large indexes.
275275
* Raise this limit if your auto-growing needs are unusually high.
276-
* <p>Used for setter/field injection via {@link #bind(PropertyValues)}, and not
277-
* applicable to constructor binding via {@link #construct}.
276+
* <p>Used for setter injection - and as of 7.1 also for field injection -
277+
* via {@link #bind(PropertyValues)}; not applicable to constructor binding
278+
* via {@link #construct}.
278279
* @see #initBeanPropertyAccess()
279280
* @see org.springframework.beans.BeanWrapper#setAutoGrowCollectionLimit
280281
*/

spring-context/src/main/java/org/springframework/validation/DirectFieldBindingResult.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
import org.jspecify.annotations.Nullable;
2020

2121
import org.springframework.beans.ConfigurablePropertyAccessor;
22-
import org.springframework.beans.DirectFieldAccessor;
2322
import org.springframework.beans.PropertyAccessorFactory;
2423

2524
/**
@@ -100,7 +99,7 @@ public final ConfigurablePropertyAccessor getPropertyAccessor() {
10099
this.directFieldAccessor = createDirectFieldAccessor();
101100
this.directFieldAccessor.setExtractOldValueForEditor(true);
102101
this.directFieldAccessor.setAutoGrowNestedPaths(this.autoGrowNestedPaths);
103-
((DirectFieldAccessor) this.directFieldAccessor).setAutoGrowCollectionLimit(this.autoGrowCollectionLimit);
102+
this.directFieldAccessor.setAutoGrowCollectionLimit(this.autoGrowCollectionLimit);
104103
}
105104
return this.directFieldAccessor;
106105
}

0 commit comments

Comments
 (0)