Fallback to Object.class if ResolvableType can't resolve
Fixes gh-11908
This commit is contained in:
@@ -262,7 +262,7 @@ public class Binder {
|
||||
}
|
||||
|
||||
private AggregateBinder<?> getAggregateBinder(Bindable<?> target, Context context) {
|
||||
Class<?> resolvedType = target.getType().resolve();
|
||||
Class<?> resolvedType = target.getType().resolve(Object.class);
|
||||
if (Map.class.isAssignableFrom(resolvedType)) {
|
||||
return new MapBinder(context);
|
||||
}
|
||||
@@ -312,7 +312,7 @@ public class Binder {
|
||||
}
|
||||
BeanPropertyBinder propertyBinder = (propertyName, propertyTarget) -> bind(
|
||||
name.append(propertyName), propertyTarget, handler, context, false);
|
||||
Class<?> type = target.getType().resolve();
|
||||
Class<?> type = target.getType().resolve(Object.class);
|
||||
if (!allowRecursiveBinding && context.hasBoundBean(type)) {
|
||||
return null;
|
||||
}
|
||||
@@ -330,7 +330,7 @@ public class Binder {
|
||||
// We know there are properties to bind so we can't bypass anything
|
||||
return false;
|
||||
}
|
||||
Class<?> resolved = target.getType().resolve();
|
||||
Class<?> resolved = target.getType().resolve(Object.class);
|
||||
if (resolved.isPrimitive() || NON_BEAN_CLASSES.contains(resolved)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ class CollectionBinder extends IndexedElementsBinder<Collection<Object>> {
|
||||
@Override
|
||||
protected Object bindAggregate(ConfigurationPropertyName name, Bindable<?> target,
|
||||
AggregateElementBinder elementBinder) {
|
||||
Class<?> collectionType = (target.getValue() == null ? target.getType().resolve()
|
||||
Class<?> collectionType = (target.getValue() == null ? target.getType().resolve(Object.class)
|
||||
: List.class);
|
||||
ResolvableType aggregateType = forClassWithGenerics(List.class,
|
||||
target.getType().asCollection().getGenerics());
|
||||
|
||||
@@ -150,7 +150,7 @@ abstract class IndexedElementsBinder<T> extends AggregateBinder<T> {
|
||||
ResolvableType... generics) {
|
||||
ResolvableType[] resolvedGenerics = new ResolvableType[generics.length];
|
||||
for (int i = 0; i < generics.length; i++) {
|
||||
resolvedGenerics[i] = forClassWithGenerics(generics[i].resolve(),
|
||||
resolvedGenerics[i] = forClassWithGenerics(generics[i].resolve(Object.class),
|
||||
generics[i].getGenerics());
|
||||
}
|
||||
return ResolvableType.forClassWithGenerics(type, resolvedGenerics);
|
||||
|
||||
@@ -54,7 +54,7 @@ class MapBinder extends AggregateBinder<Map<Object, Object>> {
|
||||
protected Object bindAggregate(ConfigurationPropertyName name, Bindable<?> target,
|
||||
AggregateElementBinder elementBinder) {
|
||||
Map<Object, Object> map = CollectionFactory.createMap(
|
||||
(target.getValue() == null ? target.getType().resolve() : Map.class), 0);
|
||||
(target.getValue() == null ? target.getType().resolve(Object.class) : Map.class), 0);
|
||||
Bindable<?> resolvedTarget = resolveTarget(target);
|
||||
boolean hasDescendants = getContext().streamSources().anyMatch((source) -> source
|
||||
.containsDescendantOf(name) == ConfigurationPropertyState.PRESENT);
|
||||
@@ -75,7 +75,7 @@ class MapBinder extends AggregateBinder<Map<Object, Object>> {
|
||||
}
|
||||
|
||||
private Bindable<?> resolveTarget(Bindable<?> target) {
|
||||
Class<?> type = target.getType().resolve();
|
||||
Class<?> type = target.getType().resolve(Object.class);
|
||||
if (Properties.class.isAssignableFrom(type)) {
|
||||
return STRING_STRING_MAP;
|
||||
}
|
||||
@@ -132,7 +132,7 @@ class MapBinder extends AggregateBinder<Map<Object, Object>> {
|
||||
|
||||
private ConfigurationPropertyName getEntryName(ConfigurationPropertySource source,
|
||||
ConfigurationPropertyName name) {
|
||||
Class<?> resolved = this.valueType.resolve();
|
||||
Class<?> resolved = this.valueType.resolve(Object.class);
|
||||
if (Collection.class.isAssignableFrom(resolved) || this.valueType.isArray()) {
|
||||
return chopNameAtNumericIndex(name);
|
||||
}
|
||||
@@ -161,7 +161,7 @@ class MapBinder extends AggregateBinder<Map<Object, Object>> {
|
||||
|
||||
private boolean isScalarValue(ConfigurationPropertySource source,
|
||||
ConfigurationPropertyName name) {
|
||||
Class<?> resolved = this.valueType.resolve();
|
||||
Class<?> resolved = this.valueType.resolve(Object.class);
|
||||
String packageName = ClassUtils.getPackageName(resolved);
|
||||
if (!packageName.startsWith("java.lang") && !resolved.isEnum()) {
|
||||
return false;
|
||||
|
||||
@@ -280,6 +280,15 @@ public class BinderTests {
|
||||
this.binder.bind("foo", target);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void bindToBeanWithUnresolvableGenerics() {
|
||||
MockConfigurationPropertySource source = new MockConfigurationPropertySource();
|
||||
source.put("foo.bar", "hello");
|
||||
this.sources.add(source);
|
||||
Bindable<GenericBean> target = Bindable.of(GenericBean.class);
|
||||
this.binder.bind("foo", target);
|
||||
}
|
||||
|
||||
public static class JavaBean {
|
||||
|
||||
private String value;
|
||||
@@ -349,4 +358,18 @@ public class BinderTests {
|
||||
|
||||
}
|
||||
|
||||
public static class GenericBean<T> {
|
||||
|
||||
private T bar;
|
||||
|
||||
|
||||
public T getBar() {
|
||||
return this.bar;
|
||||
}
|
||||
|
||||
public void setBar(T bar) {
|
||||
this.bar = bar;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user