Hey, recently I tried to debug the source code of beans components. branch: remotes/origin/5.1.x file: https://github.com/spring-projects/spring-framework/blob/master/spring-beans/src/main/java/org/springframework/beans/AbstractNestablePropertyAccessor.java line: 391 accessor.setAutoGrowNestedPaths(true);
When I execute here, my keys are non-null, but the getPropertyValue method sets DefaultValue when keys are non-null, so getPropertyValue should return to a non-null collection.
private Object getPropertyHoldingValue(PropertyTokenHolder tokens) {
// Apply indexes and map keys: fetch value for all keys but the last one.
Assert.state(tokens.keys != null, "No token keys");
PropertyTokenHolder getterTokens = new PropertyTokenHolder(tokens.actualName);
getterTokens.canonicalName = tokens.canonicalName;
getterTokens.keys = new String[tokens.keys.length - 1];
System.arraycopy(tokens.keys, 0, getterTokens.keys, 0, tokens.keys.length - 1);
Object propValue;
try {
// call getPropertyValue , keys must be not null
propValue = getPropertyValue(getterTokens);
}
catch (NotReadablePropertyException ex) {
throw new NotWritablePropertyException(getRootClass(), this.nestedPath + tokens.canonicalName,
"Cannot access indexed value in property referenced " +
"in indexed property path '" + tokens.canonicalName + "'", ex);
}
// why check that propValue is null after calling getPropertyValue?
if (propValue == null) {
// null map value case
if (isAutoGrowNestedPaths()) {
int lastKeyIndex = tokens.canonicalName.lastIndexOf('[');
getterTokens.canonicalName = tokens.canonicalName.substring(0, lastKeyIndex);
propValue = setDefaultValue(getterTokens);
}
else {
throw new NullValueInNestedPathException(getRootClass(), this.nestedPath + tokens.canonicalName,
"Cannot access indexed value in property referenced " +
"in indexed property path '" + tokens.canonicalName + "': returned null");
}
}
return propValue;
}
protected Object getPropertyValue(PropertyTokenHolder tokens) throws BeansException {
String propertyName = tokens.canonicalName;
String actualName = tokens.actualName;
PropertyHandler ph = getLocalPropertyHandler(actualName);
if (ph == null || !ph.isReadable()) {
throw new NotReadablePropertyException(getRootClass(), this.nestedPath + propertyName);
}
try {
Object value = ph.getValue();
// key are not-null
if (tokens.keys != null) {
if (value == null) {
// the AutoGrowNestedPaths enabled
if (isAutoGrowNestedPaths()) {
// this value not null
value = setDefaultValue(new PropertyTokenHolder(tokens.actualName));
}
else {
throw new NullValueInNestedPathException(getRootClass(), this.nestedPath + propertyName,
"Cannot access indexed value of property referenced in indexed " +
"property path '" + propertyName + "': returned null");
}
}
The question is why you check that propValue is null after calling getPropertyValue. Isn't this done in getPropertyValue?