|
|
|
|
@ -1,5 +1,5 @@
@@ -1,5 +1,5 @@
|
|
|
|
|
/* |
|
|
|
|
* Copyright 2012-2020 the original author or authors. |
|
|
|
|
* Copyright 2012-2022 the original author or authors. |
|
|
|
|
* |
|
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
|
|
|
* you may not use this file except in compliance with the License. |
|
|
|
|
@ -17,6 +17,7 @@
@@ -17,6 +17,7 @@
|
|
|
|
|
package org.springframework.boot.context.properties.bind; |
|
|
|
|
|
|
|
|
|
import java.lang.annotation.Annotation; |
|
|
|
|
import java.lang.reflect.Array; |
|
|
|
|
import java.lang.reflect.Constructor; |
|
|
|
|
import java.lang.reflect.Modifier; |
|
|
|
|
import java.lang.reflect.Parameter; |
|
|
|
|
@ -25,6 +26,7 @@ import java.util.Collection;
@@ -25,6 +26,7 @@ import java.util.Collection;
|
|
|
|
|
import java.util.Collections; |
|
|
|
|
import java.util.List; |
|
|
|
|
import java.util.Map; |
|
|
|
|
import java.util.Optional; |
|
|
|
|
|
|
|
|
|
import kotlin.reflect.KFunction; |
|
|
|
|
import kotlin.reflect.KParameter; |
|
|
|
|
@ -32,6 +34,7 @@ import kotlin.reflect.jvm.ReflectJvmMapping;
@@ -32,6 +34,7 @@ import kotlin.reflect.jvm.ReflectJvmMapping;
|
|
|
|
|
|
|
|
|
|
import org.springframework.beans.BeanUtils; |
|
|
|
|
import org.springframework.boot.context.properties.source.ConfigurationPropertyName; |
|
|
|
|
import org.springframework.core.CollectionFactory; |
|
|
|
|
import org.springframework.core.DefaultParameterNameDiscoverer; |
|
|
|
|
import org.springframework.core.KotlinDetector; |
|
|
|
|
import org.springframework.core.MethodParameter; |
|
|
|
|
@ -101,7 +104,7 @@ class ValueObjectBinder implements DataObjectBinder {
@@ -101,7 +104,7 @@ class ValueObjectBinder implements DataObjectBinder {
|
|
|
|
|
if (annotation instanceof DefaultValue) { |
|
|
|
|
String[] defaultValue = ((DefaultValue) annotation).value(); |
|
|
|
|
if (defaultValue.length == 0) { |
|
|
|
|
return getNewInstanceIfPossible(context, type); |
|
|
|
|
return getNewDefaultValueInstanceIfPossible(context, type); |
|
|
|
|
} |
|
|
|
|
return convertDefaultValue(context.getConverter(), defaultValue, type, annotations); |
|
|
|
|
} |
|
|
|
|
@ -124,7 +127,7 @@ class ValueObjectBinder implements DataObjectBinder {
@@ -124,7 +127,7 @@ class ValueObjectBinder implements DataObjectBinder {
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@SuppressWarnings("unchecked") |
|
|
|
|
private <T> T getNewInstanceIfPossible(Binder.Context context, ResolvableType type) { |
|
|
|
|
private <T> T getNewDefaultValueInstanceIfPossible(Binder.Context context, ResolvableType type) { |
|
|
|
|
Class<T> resolved = (Class<T>) type.resolve(); |
|
|
|
|
Assert.state(resolved == null || isEmptyDefaultValueAllowed(resolved), |
|
|
|
|
() -> "Parameter of type " + type + " must have a non-empty default value."); |
|
|
|
|
@ -132,14 +135,27 @@ class ValueObjectBinder implements DataObjectBinder {
@@ -132,14 +135,27 @@ class ValueObjectBinder implements DataObjectBinder {
|
|
|
|
|
if (instance != null) { |
|
|
|
|
return instance; |
|
|
|
|
} |
|
|
|
|
return (resolved != null) ? BeanUtils.instantiateClass(resolved) : null; |
|
|
|
|
if (resolved != null) { |
|
|
|
|
if (Optional.class == resolved) { |
|
|
|
|
return (T) Optional.empty(); |
|
|
|
|
} |
|
|
|
|
if (Collection.class.isAssignableFrom(resolved)) { |
|
|
|
|
return (T) CollectionFactory.createCollection(resolved, 0); |
|
|
|
|
} |
|
|
|
|
if (Map.class.isAssignableFrom(resolved)) { |
|
|
|
|
return (T) CollectionFactory.createMap(resolved, 0); |
|
|
|
|
} |
|
|
|
|
if (resolved.isArray()) { |
|
|
|
|
return (T) Array.newInstance(resolved.getComponentType(), 0); |
|
|
|
|
} |
|
|
|
|
return BeanUtils.instantiateClass(resolved); |
|
|
|
|
} |
|
|
|
|
return null; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private boolean isEmptyDefaultValueAllowed(Class<?> type) { |
|
|
|
|
if (type.isPrimitive() || type.isEnum() || isAggregate(type) || type.getName().startsWith("java.lang")) { |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
return true; |
|
|
|
|
return (Optional.class == type || isAggregate(type)) |
|
|
|
|
|| !(type.isPrimitive() || type.isEnum() || type.getName().startsWith("java.lang")); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private boolean isAggregate(Class<?> type) { |
|
|
|
|
|