|
|
|
@ -28,6 +28,7 @@ import java.util.function.Supplier;
|
|
|
|
|
import org.springframework.beans.BeanUtils;
|
|
|
|
|
import org.springframework.boot.context.properties.source.ConfigurationPropertyName;
|
|
|
|
|
import org.springframework.boot.context.properties.source.ConfigurationPropertyState;
|
|
|
|
|
import org.springframework.core.MethodParameter;
|
|
|
|
|
import org.springframework.core.ResolvableType;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
@ -91,9 +92,12 @@ class JavaBeanBinder implements BeanBinder {
|
|
|
|
|
|
|
|
|
|
private final Class<?> type;
|
|
|
|
|
|
|
|
|
|
private final ResolvableType resolvableType;
|
|
|
|
|
|
|
|
|
|
private final Map<String, BeanProperty> properties = new LinkedHashMap<>();
|
|
|
|
|
|
|
|
|
|
Bean(Class<?> type) {
|
|
|
|
|
Bean(ResolvableType resolvableType, Class<?> type) {
|
|
|
|
|
this.resolvableType = resolvableType;
|
|
|
|
|
this.type = type;
|
|
|
|
|
putProperties(type);
|
|
|
|
|
}
|
|
|
|
@ -123,17 +127,17 @@ class JavaBeanBinder implements BeanBinder {
|
|
|
|
|
int parameterCount = method.getParameterCount();
|
|
|
|
|
if (name.startsWith("get") && parameterCount == 0) {
|
|
|
|
|
name = Introspector.decapitalize(name.substring(3));
|
|
|
|
|
this.properties.computeIfAbsent(name, BeanProperty::new)
|
|
|
|
|
this.properties.computeIfAbsent(name, n -> new BeanProperty(n, this.resolvableType))
|
|
|
|
|
.addGetter(method);
|
|
|
|
|
}
|
|
|
|
|
else if (name.startsWith("is") && parameterCount == 0) {
|
|
|
|
|
name = Introspector.decapitalize(name.substring(2));
|
|
|
|
|
this.properties.computeIfAbsent(name, BeanProperty::new)
|
|
|
|
|
this.properties.computeIfAbsent(name, n -> new BeanProperty(n, this.resolvableType))
|
|
|
|
|
.addGetter(method);
|
|
|
|
|
}
|
|
|
|
|
else if (name.startsWith("set") && parameterCount == 1) {
|
|
|
|
|
name = Introspector.decapitalize(name.substring(3));
|
|
|
|
|
this.properties.computeIfAbsent(name, BeanProperty::new)
|
|
|
|
|
this.properties.computeIfAbsent(name, n -> new BeanProperty(n, this.resolvableType))
|
|
|
|
|
.addSetter(method);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -169,7 +173,7 @@ class JavaBeanBinder implements BeanBinder {
|
|
|
|
|
|
|
|
|
|
@SuppressWarnings("unchecked")
|
|
|
|
|
public static <T> Bean<T> get(Bindable<T> bindable, boolean canCallGetValue) {
|
|
|
|
|
Class<?> type = bindable.getType().resolve();
|
|
|
|
|
Class<?> type = bindable.getType().resolve(Object.class);
|
|
|
|
|
Supplier<T> value = bindable.getValue();
|
|
|
|
|
T instance = null;
|
|
|
|
|
if (canCallGetValue && value != null) {
|
|
|
|
@ -181,7 +185,7 @@ class JavaBeanBinder implements BeanBinder {
|
|
|
|
|
}
|
|
|
|
|
Bean<?> bean = Bean.cached;
|
|
|
|
|
if (bean == null || !type.equals(bean.getType())) {
|
|
|
|
|
bean = new Bean<>(type);
|
|
|
|
|
bean = new Bean<>(bindable.getType(), type);
|
|
|
|
|
cached = bean;
|
|
|
|
|
}
|
|
|
|
|
return (Bean<T>) bean;
|
|
|
|
@ -229,14 +233,17 @@ class JavaBeanBinder implements BeanBinder {
|
|
|
|
|
|
|
|
|
|
private final String name;
|
|
|
|
|
|
|
|
|
|
private final ResolvableType declaringClassType;
|
|
|
|
|
|
|
|
|
|
private Method getter;
|
|
|
|
|
|
|
|
|
|
private Method setter;
|
|
|
|
|
|
|
|
|
|
private Field field;
|
|
|
|
|
|
|
|
|
|
BeanProperty(String name) {
|
|
|
|
|
BeanProperty(String name, ResolvableType declaringClassType) {
|
|
|
|
|
this.name = BeanPropertyName.toDashedForm(name);
|
|
|
|
|
this.declaringClassType = declaringClassType;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void addGetter(Method getter) {
|
|
|
|
@ -263,9 +270,11 @@ class JavaBeanBinder implements BeanBinder {
|
|
|
|
|
|
|
|
|
|
public ResolvableType getType() {
|
|
|
|
|
if (this.setter != null) {
|
|
|
|
|
return ResolvableType.forMethodParameter(this.setter, 0);
|
|
|
|
|
MethodParameter methodParameter = new MethodParameter(this.setter, 0);
|
|
|
|
|
return ResolvableType.forMethodParameter(methodParameter, this.declaringClassType);
|
|
|
|
|
}
|
|
|
|
|
return ResolvableType.forMethodReturnType(this.getter);
|
|
|
|
|
MethodParameter methodParameter = new MethodParameter(this.getter, -1);
|
|
|
|
|
return ResolvableType.forMethodParameter(methodParameter, this.declaringClassType);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public Annotation[] getAnnotations() {
|
|
|
|
|