commit
75f55cc35a
|
@ -18,7 +18,7 @@ package org.springframework.boot.context.properties;
|
|||
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||
import org.springframework.boot.context.properties.ConfigurationPropertiesBean.BindMethod;
|
||||
import org.springframework.boot.context.properties.bind.BindMethod;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.core.AttributeAccessor;
|
||||
|
|
|
@ -61,19 +61,22 @@ import org.springframework.validation.annotation.Validated;
|
|||
*/
|
||||
public final class ConfigurationPropertiesBean {
|
||||
|
||||
private static final org.springframework.boot.context.properties.bind.BindMethod JAVA_BEAN_BIND_METHOD = //
|
||||
org.springframework.boot.context.properties.bind.BindMethod.JAVA_BEAN;
|
||||
|
||||
private static final org.springframework.boot.context.properties.bind.BindMethod VALUE_OBJECT_BIND_METHOD = //
|
||||
org.springframework.boot.context.properties.bind.BindMethod.VALUE_OBJECT;
|
||||
|
||||
private final String name;
|
||||
|
||||
private final Object instance;
|
||||
|
||||
private final Bindable<?> bindTarget;
|
||||
|
||||
private final BindMethod bindMethod;
|
||||
|
||||
private ConfigurationPropertiesBean(String name, Object instance, Bindable<?> bindTarget, BindMethod bindMethod) {
|
||||
private ConfigurationPropertiesBean(String name, Object instance, Bindable<?> bindTarget) {
|
||||
this.name = name;
|
||||
this.instance = instance;
|
||||
this.bindTarget = bindTarget;
|
||||
this.bindMethod = (bindMethod != null) ? bindMethod : BindMethod.get(bindTarget);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -102,10 +105,13 @@ public final class ConfigurationPropertiesBean {
|
|||
|
||||
/**
|
||||
* Return the property binding method that was used for the bean.
|
||||
* @return the bind type
|
||||
* @return the bind method
|
||||
* @deprecated since 3.0.8 for removal in 3.3.0 in favor of {@link #asBindTarget} and
|
||||
* {@link Bindable#getBindMethod}
|
||||
*/
|
||||
@Deprecated(since = "3.0.8", forRemoval = true)
|
||||
public BindMethod getBindMethod() {
|
||||
return this.bindMethod;
|
||||
return BindMethod.from(this.bindTarget.getBindMethod());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -206,14 +212,17 @@ public final class ConfigurationPropertiesBean {
|
|||
if (bindTarget == null) {
|
||||
return null;
|
||||
}
|
||||
BindMethod bindMethod = BindMethodAttribute.get(applicationContext, beanName);
|
||||
if (bindMethod == null && factoryMethod != null) {
|
||||
bindMethod = BindMethod.JAVA_BEAN;
|
||||
bindTarget = bindTarget.withBindMethod(BindMethodAttribute.get(applicationContext, beanName));
|
||||
if (bindTarget.getBindMethod() == null && factoryMethod != null) {
|
||||
bindTarget = bindTarget.withBindMethod(JAVA_BEAN_BIND_METHOD);
|
||||
}
|
||||
if (bindTarget != null && bindMethod != BindMethod.VALUE_OBJECT) {
|
||||
if (bindTarget.getBindMethod() == null) {
|
||||
bindTarget = bindTarget.withBindMethod(deduceBindMethod(bindTarget));
|
||||
}
|
||||
if (bindTarget.getBindMethod() != VALUE_OBJECT_BIND_METHOD) {
|
||||
bindTarget = bindTarget.withExistingValue(bean);
|
||||
}
|
||||
return create(beanName, bean, bindTarget, bindMethod);
|
||||
return create(beanName, bean, bindTarget);
|
||||
}
|
||||
|
||||
private static Method findFactoryMethod(ApplicationContext applicationContext, String beanName) {
|
||||
|
@ -263,10 +272,9 @@ public final class ConfigurationPropertiesBean {
|
|||
|
||||
static ConfigurationPropertiesBean forValueObject(Class<?> beanType, String beanName) {
|
||||
Bindable<Object> bindTarget = createBindTarget(null, beanType, null);
|
||||
ConfigurationPropertiesBean propertiesBean = create(beanName, null, bindTarget, null);
|
||||
Assert.state(propertiesBean != null && propertiesBean.getBindMethod() == BindMethod.VALUE_OBJECT,
|
||||
Assert.state(bindTarget != null && deduceBindMethod(bindTarget) == VALUE_OBJECT_BIND_METHOD,
|
||||
() -> "Bean '" + beanName + "' is not a @ConfigurationProperties value object");
|
||||
return propertiesBean;
|
||||
return create(beanName, null, bindTarget.withBindMethod(VALUE_OBJECT_BIND_METHOD));
|
||||
}
|
||||
|
||||
private static Bindable<Object> createBindTarget(Object bean, Class<?> beanType, Method factoryMethod) {
|
||||
|
@ -307,14 +315,40 @@ public final class ConfigurationPropertiesBean {
|
|||
: MergedAnnotation.missing();
|
||||
}
|
||||
|
||||
private static ConfigurationPropertiesBean create(String name, Object instance, Bindable<Object> bindTarget,
|
||||
BindMethod bindMethod) {
|
||||
return (bindTarget != null) ? new ConfigurationPropertiesBean(name, instance, bindTarget, bindMethod) : null;
|
||||
private static ConfigurationPropertiesBean create(String name, Object instance, Bindable<Object> bindTarget) {
|
||||
return (bindTarget != null) ? new ConfigurationPropertiesBean(name, instance, bindTarget) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deduce the {@code BindMethod} that should be used for the given type.
|
||||
* @param type the source type
|
||||
* @return the bind method to use
|
||||
*/
|
||||
static org.springframework.boot.context.properties.bind.BindMethod deduceBindMethod(Class<?> type) {
|
||||
return deduceBindMethod(BindConstructorProvider.DEFAULT.getBindConstructor(type, false));
|
||||
}
|
||||
|
||||
/**
|
||||
* Deduce the {@code BindMethod} that should be used for the given {@link Bindable}.
|
||||
* @param bindable the source bindable
|
||||
* @return the bind method to use
|
||||
*/
|
||||
static org.springframework.boot.context.properties.bind.BindMethod deduceBindMethod(Bindable<Object> bindable) {
|
||||
return deduceBindMethod(BindConstructorProvider.DEFAULT.getBindConstructor(bindable, false));
|
||||
}
|
||||
|
||||
private static org.springframework.boot.context.properties.bind.BindMethod deduceBindMethod(
|
||||
Constructor<?> bindConstructor) {
|
||||
return (bindConstructor != null) ? VALUE_OBJECT_BIND_METHOD : JAVA_BEAN_BIND_METHOD;
|
||||
}
|
||||
|
||||
/**
|
||||
* The binding method that is used for the bean.
|
||||
*
|
||||
* @deprecated since 3.0.8 for removal in 3.3.0 in favor of
|
||||
* {@link org.springframework.boot.context.properties.bind.BindMethod}
|
||||
*/
|
||||
@Deprecated(since = "3.0.8", forRemoval = true)
|
||||
public enum BindMethod {
|
||||
|
||||
/**
|
||||
|
@ -327,16 +361,14 @@ public final class ConfigurationPropertiesBean {
|
|||
*/
|
||||
VALUE_OBJECT;
|
||||
|
||||
static BindMethod get(Class<?> type) {
|
||||
return get(BindConstructorProvider.DEFAULT.getBindConstructor(type, false));
|
||||
}
|
||||
|
||||
static BindMethod get(Bindable<?> bindable) {
|
||||
return get(BindConstructorProvider.DEFAULT.getBindConstructor(bindable, false));
|
||||
}
|
||||
|
||||
private static BindMethod get(Constructor<?> bindConstructor) {
|
||||
return (bindConstructor != null) ? VALUE_OBJECT : JAVA_BEAN;
|
||||
static BindMethod from(org.springframework.boot.context.properties.bind.BindMethod bindMethod) {
|
||||
if (bindMethod == null) {
|
||||
return null;
|
||||
}
|
||||
return switch (bindMethod) {
|
||||
case VALUE_OBJECT -> BindMethod.VALUE_OBJECT;
|
||||
case JAVA_BEAN -> BindMethod.JAVA_BEAN;
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ import org.springframework.beans.factory.ListableBeanFactory;
|
|||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||
import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||
import org.springframework.boot.context.properties.ConfigurationPropertiesBean.BindMethod;
|
||||
import org.springframework.boot.context.properties.bind.BindMethod;
|
||||
import org.springframework.core.annotation.MergedAnnotation;
|
||||
import org.springframework.core.annotation.MergedAnnotations;
|
||||
import org.springframework.core.annotation.MergedAnnotations.SearchStrategy;
|
||||
|
@ -90,7 +90,7 @@ final class ConfigurationPropertiesBeanRegistrar {
|
|||
}
|
||||
|
||||
private BeanDefinition createBeanDefinition(String beanName, Class<?> type) {
|
||||
BindMethod bindMethod = BindMethod.get(type);
|
||||
BindMethod bindMethod = ConfigurationPropertiesBean.deduceBindMethod(type);
|
||||
RootBeanDefinition definition = new RootBeanDefinition(type);
|
||||
BindMethodAttribute.set(definition, bindMethod);
|
||||
if (bindMethod == BindMethod.VALUE_OBJECT) {
|
||||
|
|
|
@ -33,7 +33,7 @@ import org.springframework.beans.factory.config.BeanDefinition;
|
|||
import org.springframework.beans.factory.support.InstanceSupplier;
|
||||
import org.springframework.beans.factory.support.RegisteredBean;
|
||||
import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||
import org.springframework.boot.context.properties.ConfigurationPropertiesBean.BindMethod;
|
||||
import org.springframework.boot.context.properties.bind.BindMethod;
|
||||
import org.springframework.javapoet.CodeBlock;
|
||||
|
||||
/**
|
||||
|
|
|
@ -22,7 +22,7 @@ import org.springframework.beans.factory.config.BeanDefinition;
|
|||
import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||
import org.springframework.boot.context.properties.ConfigurationPropertiesBean.BindMethod;
|
||||
import org.springframework.boot.context.properties.bind.BindMethod;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.core.Ordered;
|
||||
|
@ -89,8 +89,9 @@ public class ConfigurationPropertiesBindingPostProcessor
|
|||
if (bean == null) {
|
||||
return;
|
||||
}
|
||||
Assert.state(bean.getBindMethod() == BindMethod.JAVA_BEAN, "Cannot bind @ConfigurationProperties for bean '"
|
||||
+ bean.getName() + "'. Ensure that @ConstructorBinding has not been applied to regular bean");
|
||||
Assert.state(bean.asBindTarget().getBindMethod() != BindMethod.VALUE_OBJECT,
|
||||
"Cannot bind @ConfigurationProperties for bean '" + bean.getName()
|
||||
+ "'. Ensure that @ConstructorBinding has not been applied to regular bean");
|
||||
try {
|
||||
this.binder.bind(bean);
|
||||
}
|
||||
|
|
|
@ -21,13 +21,13 @@ import java.lang.reflect.Constructor;
|
|||
import org.springframework.beans.factory.InjectionPoint;
|
||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
import org.springframework.beans.factory.UnsatisfiedDependencyException;
|
||||
import org.springframework.boot.context.properties.ConfigurationPropertiesBean.BindMethod;
|
||||
import org.springframework.boot.context.properties.bind.BindMethod;
|
||||
import org.springframework.boot.context.properties.bind.ConstructorBinding;
|
||||
import org.springframework.boot.diagnostics.FailureAnalysis;
|
||||
import org.springframework.boot.diagnostics.analyzer.AbstractInjectionFailureAnalyzer;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.core.annotation.MergedAnnotation;
|
||||
import org.springframework.core.annotation.MergedAnnotations;
|
||||
import org.springframework.core.annotation.MergedAnnotations.SearchStrategy;
|
||||
|
||||
/**
|
||||
* An {@link AbstractInjectionFailureAnalyzer} for
|
||||
|
@ -61,14 +61,15 @@ class NotConstructorBoundInjectionFailureAnalyzer
|
|||
}
|
||||
|
||||
private boolean isConstructorBindingConfigurationProperties(InjectionPoint injectionPoint) {
|
||||
if (injectionPoint != null && injectionPoint.getMember() instanceof Constructor<?> constructor) {
|
||||
Class<?> declaringClass = constructor.getDeclaringClass();
|
||||
MergedAnnotation<ConfigurationProperties> configurationProperties = MergedAnnotations.from(declaringClass)
|
||||
.get(ConfigurationProperties.class);
|
||||
return configurationProperties.isPresent()
|
||||
&& BindMethod.get(constructor.getDeclaringClass()) == BindMethod.VALUE_OBJECT;
|
||||
}
|
||||
return false;
|
||||
return (injectionPoint != null && injectionPoint.getMember() instanceof Constructor<?> constructor)
|
||||
? isConstructorBindingConfigurationProperties(constructor) : false;
|
||||
}
|
||||
|
||||
private boolean isConstructorBindingConfigurationProperties(Constructor<?> constructor) {
|
||||
Class<?> declaringClass = constructor.getDeclaringClass();
|
||||
BindMethod bindMethod = ConfigurationPropertiesBean.deduceBindMethod(declaringClass);
|
||||
return MergedAnnotations.from(declaringClass, SearchStrategy.TYPE_HIERARCHY)
|
||||
.isPresent(ConfigurationProperties.class) && bindMethod == BindMethod.VALUE_OBJECT;
|
||||
}
|
||||
|
||||
private InjectionPoint findInjectionPoint(Throwable failure) {
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Copyright 2012-2023 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.context.properties.bind;
|
||||
|
||||
/**
|
||||
* Configuration property binding methods.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
* @since 3.0.8
|
||||
*/
|
||||
public enum BindMethod {
|
||||
|
||||
/**
|
||||
* Java Bean using getter/setter binding.
|
||||
*/
|
||||
JAVA_BEAN,
|
||||
|
||||
/**
|
||||
* Value object using constructor binding.
|
||||
*/
|
||||
VALUE_OBJECT;
|
||||
|
||||
}
|
|
@ -57,13 +57,16 @@ public final class Bindable<T> {
|
|||
|
||||
private final EnumSet<BindRestriction> bindRestrictions;
|
||||
|
||||
private final BindMethod bindMethod;
|
||||
|
||||
private Bindable(ResolvableType type, ResolvableType boxedType, Supplier<T> value, Annotation[] annotations,
|
||||
EnumSet<BindRestriction> bindRestrictions) {
|
||||
EnumSet<BindRestriction> bindRestrictions, BindMethod bindMethod) {
|
||||
this.type = type;
|
||||
this.boxedType = boxedType;
|
||||
this.value = value;
|
||||
this.annotations = annotations;
|
||||
this.bindRestrictions = bindRestrictions;
|
||||
this.bindMethod = bindMethod;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -124,6 +127,16 @@ public final class Bindable<T> {
|
|||
return this.bindRestrictions.contains(bindRestriction);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link BindMethod method} to be used to bind this bindable, or
|
||||
* {@code null} if no specific binding method is required.
|
||||
* @return the bind method or {@code null}
|
||||
* @since 3.0.8
|
||||
*/
|
||||
public BindMethod getBindMethod() {
|
||||
return this.bindMethod;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
|
@ -137,6 +150,7 @@ public final class Bindable<T> {
|
|||
result = result && nullSafeEquals(this.type.resolve(), other.type.resolve());
|
||||
result = result && nullSafeEquals(this.annotations, other.annotations);
|
||||
result = result && nullSafeEquals(this.bindRestrictions, other.bindRestrictions);
|
||||
result = result && nullSafeEquals(this.bindMethod, other.bindMethod);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -147,6 +161,7 @@ public final class Bindable<T> {
|
|||
result = prime * result + ObjectUtils.nullSafeHashCode(this.type);
|
||||
result = prime * result + ObjectUtils.nullSafeHashCode(this.annotations);
|
||||
result = prime * result + ObjectUtils.nullSafeHashCode(this.bindRestrictions);
|
||||
result = prime * result + ObjectUtils.nullSafeHashCode(this.bindMethod);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -156,6 +171,7 @@ public final class Bindable<T> {
|
|||
creator.append("type", this.type);
|
||||
creator.append("value", (this.value != null) ? "provided" : "none");
|
||||
creator.append("annotations", this.annotations);
|
||||
creator.append("bindMethod", this.bindMethod);
|
||||
return creator.toString();
|
||||
}
|
||||
|
||||
|
@ -170,11 +186,12 @@ public final class Bindable<T> {
|
|||
*/
|
||||
public Bindable<T> withAnnotations(Annotation... annotations) {
|
||||
return new Bindable<>(this.type, this.boxedType, this.value,
|
||||
(annotations != null) ? annotations : NO_ANNOTATIONS, NO_BIND_RESTRICTIONS);
|
||||
(annotations != null) ? annotations : NO_ANNOTATIONS, NO_BIND_RESTRICTIONS, this.bindMethod);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an updated {@link Bindable} instance with an existing value.
|
||||
* Create an updated {@link Bindable} instance with an existing value. Implies that
|
||||
* Java Bean binding will be used.
|
||||
* @param existingValue the existing value
|
||||
* @return an updated {@link Bindable}
|
||||
*/
|
||||
|
@ -182,8 +199,11 @@ public final class Bindable<T> {
|
|||
Assert.isTrue(
|
||||
existingValue == null || this.type.isArray() || this.boxedType.resolve().isInstance(existingValue),
|
||||
() -> "ExistingValue must be an instance of " + this.type);
|
||||
Assert.state(this.bindMethod != BindMethod.VALUE_OBJECT,
|
||||
() -> "An existing value cannot be provided when binding as a value object");
|
||||
Supplier<T> value = (existingValue != null) ? () -> existingValue : null;
|
||||
return new Bindable<>(this.type, this.boxedType, value, this.annotations, this.bindRestrictions);
|
||||
return new Bindable<>(this.type, this.boxedType, value, this.annotations, this.bindRestrictions,
|
||||
BindMethod.JAVA_BEAN);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -192,7 +212,8 @@ public final class Bindable<T> {
|
|||
* @return an updated {@link Bindable}
|
||||
*/
|
||||
public Bindable<T> withSuppliedValue(Supplier<T> suppliedValue) {
|
||||
return new Bindable<>(this.type, this.boxedType, suppliedValue, this.annotations, this.bindRestrictions);
|
||||
return new Bindable<>(this.type, this.boxedType, suppliedValue, this.annotations, this.bindRestrictions,
|
||||
this.bindMethod);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -204,7 +225,23 @@ public final class Bindable<T> {
|
|||
public Bindable<T> withBindRestrictions(BindRestriction... additionalRestrictions) {
|
||||
EnumSet<BindRestriction> bindRestrictions = EnumSet.copyOf(this.bindRestrictions);
|
||||
bindRestrictions.addAll(Arrays.asList(additionalRestrictions));
|
||||
return new Bindable<>(this.type, this.boxedType, this.value, this.annotations, bindRestrictions);
|
||||
return new Bindable<>(this.type, this.boxedType, this.value, this.annotations, bindRestrictions,
|
||||
this.bindMethod);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an updated {@link Bindable} instance with a specifc bind method. To use
|
||||
* {@link BindMethod#VALUE_OBJECT value object binding}, the current instance must not
|
||||
* have an existing or supplied value.
|
||||
* @param bindMethod the method to use to bind the bindable
|
||||
* @return an updated {@link Bindable}
|
||||
* @since 3.0.8
|
||||
*/
|
||||
public Bindable<T> withBindMethod(BindMethod bindMethod) {
|
||||
Assert.state(bindMethod != BindMethod.VALUE_OBJECT || this.value == null,
|
||||
() -> "Value object binding cannot be used with an existing or supplied value");
|
||||
return new Bindable<>(this.type, this.boxedType, this.value, this.annotations, this.bindRestrictions,
|
||||
bindMethod);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -277,7 +314,7 @@ public final class Bindable<T> {
|
|||
public static <T> Bindable<T> of(ResolvableType type) {
|
||||
Assert.notNull(type, "Type must not be null");
|
||||
ResolvableType boxedType = box(type);
|
||||
return new Bindable<>(type, boxedType, null, NO_ANNOTATIONS, NO_BIND_RESTRICTIONS);
|
||||
return new Bindable<>(type, boxedType, null, NO_ANNOTATIONS, NO_BIND_RESTRICTIONS, null);
|
||||
}
|
||||
|
||||
private static ResolvableType box(ResolvableType type) {
|
||||
|
|
|
@ -21,6 +21,7 @@ import java.util.Arrays;
|
|||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Deque;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
@ -64,7 +65,7 @@ public class Binder {
|
|||
|
||||
private final BindHandler defaultBindHandler;
|
||||
|
||||
private final List<DataObjectBinder> dataObjectBinders;
|
||||
private final Map<BindMethod, List<DataObjectBinder>> dataObjectBinders;
|
||||
|
||||
/**
|
||||
* Create a new {@link Binder} instance for the specified sources. A
|
||||
|
@ -194,7 +195,11 @@ public class Binder {
|
|||
}
|
||||
ValueObjectBinder valueObjectBinder = new ValueObjectBinder(constructorProvider);
|
||||
JavaBeanBinder javaBeanBinder = JavaBeanBinder.INSTANCE;
|
||||
this.dataObjectBinders = Collections.unmodifiableList(Arrays.asList(valueObjectBinder, javaBeanBinder));
|
||||
Map<BindMethod, List<DataObjectBinder>> dataObjectBinders = new HashMap<>();
|
||||
dataObjectBinders.put(BindMethod.VALUE_OBJECT, List.of(valueObjectBinder));
|
||||
dataObjectBinders.put(BindMethod.JAVA_BEAN, List.of(javaBeanBinder));
|
||||
dataObjectBinders.put(null, List.of(valueObjectBinder, javaBeanBinder));
|
||||
this.dataObjectBinders = Collections.unmodifiableMap(dataObjectBinders);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -365,7 +370,7 @@ public class Binder {
|
|||
}
|
||||
|
||||
private Object create(Bindable<?> target, Context context) {
|
||||
for (DataObjectBinder dataObjectBinder : this.dataObjectBinders) {
|
||||
for (DataObjectBinder dataObjectBinder : this.dataObjectBinders.get(target.getBindMethod())) {
|
||||
Object instance = dataObjectBinder.create(target, context);
|
||||
if (instance != null) {
|
||||
return instance;
|
||||
|
@ -466,13 +471,14 @@ public class Binder {
|
|||
return null;
|
||||
}
|
||||
Class<?> type = target.getType().resolve(Object.class);
|
||||
BindMethod bindMethod = target.getBindMethod();
|
||||
if (!allowRecursiveBinding && context.isBindingDataObject(type)) {
|
||||
return null;
|
||||
}
|
||||
DataObjectPropertyBinder propertyBinder = (propertyName, propertyTarget) -> bind(name.append(propertyName),
|
||||
propertyTarget, handler, context, false, false);
|
||||
return context.withDataObject(type, () -> {
|
||||
for (DataObjectBinder dataObjectBinder : this.dataObjectBinders) {
|
||||
for (DataObjectBinder dataObjectBinder : this.dataObjectBinders.get(bindMethod)) {
|
||||
Object instance = dataObjectBinder.bind(name, target, context, propertyBinder);
|
||||
if (instance != null) {
|
||||
return instance;
|
||||
|
|
|
@ -25,7 +25,7 @@ import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
|||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||
import org.springframework.beans.factory.support.GenericBeanDefinition;
|
||||
import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||
import org.springframework.boot.context.properties.ConfigurationPropertiesBean.BindMethod;
|
||||
import org.springframework.boot.context.properties.bind.BindMethod;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
|
||||
|
|
|
@ -26,8 +26,8 @@ import org.junit.jupiter.api.Test;
|
|||
import org.junit.jupiter.api.function.ThrowingConsumer;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.context.properties.ConfigurationPropertiesBean.BindMethod;
|
||||
import org.springframework.boot.context.properties.bind.BindConstructorProvider;
|
||||
import org.springframework.boot.context.properties.bind.BindMethod;
|
||||
import org.springframework.boot.context.properties.bind.Bindable;
|
||||
import org.springframework.boot.context.properties.bind.ConstructorBinding;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
|
@ -64,19 +64,19 @@ class ConfigurationPropertiesBeanTests {
|
|||
assertThat(component.getInstance()).isInstanceOf(AnnotatedComponent.class);
|
||||
assertThat(component.getAnnotation()).isNotNull();
|
||||
assertThat(component.getType()).isEqualTo(AnnotatedComponent.class);
|
||||
assertThat(component.getBindMethod()).isEqualTo(BindMethod.JAVA_BEAN);
|
||||
assertThat(component.asBindTarget().getBindMethod()).isEqualTo(BindMethod.JAVA_BEAN);
|
||||
ConfigurationPropertiesBean bean = all.get("annotatedBean");
|
||||
assertThat(bean.getName()).isEqualTo("annotatedBean");
|
||||
assertThat(bean.getInstance()).isInstanceOf(AnnotatedBean.class);
|
||||
assertThat(bean.getType()).isEqualTo(AnnotatedBean.class);
|
||||
assertThat(bean.getAnnotation()).isNotNull();
|
||||
assertThat(bean.getBindMethod()).isEqualTo(BindMethod.JAVA_BEAN);
|
||||
assertThat(bean.asBindTarget().getBindMethod()).isEqualTo(BindMethod.JAVA_BEAN);
|
||||
ConfigurationPropertiesBean valueObject = all.get(ValueObject.class.getName());
|
||||
assertThat(valueObject.getName()).isEqualTo(ValueObject.class.getName());
|
||||
assertThat(valueObject.getInstance()).isInstanceOf(ValueObject.class);
|
||||
assertThat(valueObject.getType()).isEqualTo(ValueObject.class);
|
||||
assertThat(valueObject.getAnnotation()).isNotNull();
|
||||
assertThat(valueObject.getBindMethod()).isEqualTo(BindMethod.VALUE_OBJECT);
|
||||
assertThat(valueObject.asBindTarget().getBindMethod()).isEqualTo(BindMethod.VALUE_OBJECT);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -113,7 +113,7 @@ class ConfigurationPropertiesBeanTests {
|
|||
assertThat(propertiesBean.getInstance()).isInstanceOf(AnnotatedComponent.class);
|
||||
assertThat(propertiesBean.getType()).isEqualTo(AnnotatedComponent.class);
|
||||
assertThat(propertiesBean.getAnnotation().prefix()).isEqualTo("prefix");
|
||||
assertThat(propertiesBean.getBindMethod()).isEqualTo(BindMethod.JAVA_BEAN);
|
||||
assertThat(propertiesBean.asBindTarget().getBindMethod()).isEqualTo(BindMethod.JAVA_BEAN);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -125,7 +125,7 @@ class ConfigurationPropertiesBeanTests {
|
|||
assertThat(propertiesBean.getInstance()).isInstanceOf(NonAnnotatedBean.class);
|
||||
assertThat(propertiesBean.getType()).isEqualTo(NonAnnotatedBean.class);
|
||||
assertThat(propertiesBean.getAnnotation().prefix()).isEqualTo("prefix");
|
||||
assertThat(propertiesBean.getBindMethod()).isEqualTo(BindMethod.JAVA_BEAN);
|
||||
assertThat(propertiesBean.asBindTarget().getBindMethod()).isEqualTo(BindMethod.JAVA_BEAN);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -138,7 +138,7 @@ class ConfigurationPropertiesBeanTests {
|
|||
assertThat(propertiesBean.getInstance()).isInstanceOf(NonAnnotatedBean.class);
|
||||
assertThat(propertiesBean.getType()).isEqualTo(NonAnnotatedBean.class);
|
||||
assertThat(propertiesBean.getAnnotation().prefix()).isEqualTo("prefix");
|
||||
assertThat(propertiesBean.getBindMethod()).isEqualTo(BindMethod.JAVA_BEAN);
|
||||
assertThat(propertiesBean.asBindTarget().getBindMethod()).isEqualTo(BindMethod.JAVA_BEAN);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -150,7 +150,7 @@ class ConfigurationPropertiesBeanTests {
|
|||
assertThat(propertiesBean.getInstance()).isInstanceOf(NonAnnotatedBean.class);
|
||||
assertThat(propertiesBean.getType()).isEqualTo(NonAnnotatedBean.class);
|
||||
assertThat(propertiesBean.getAnnotation().prefix()).isEqualTo("prefix");
|
||||
assertThat(propertiesBean.getBindMethod()).isEqualTo(BindMethod.JAVA_BEAN);
|
||||
assertThat(propertiesBean.asBindTarget().getBindMethod()).isEqualTo(BindMethod.JAVA_BEAN);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -158,7 +158,7 @@ class ConfigurationPropertiesBeanTests {
|
|||
void getWhenHasFactoryMethodBindsUsingMethodReturnType() throws Throwable {
|
||||
get(NonAnnotatedGenericBeanConfiguration.class, "nonAnnotatedGenericBean", (propertiesBean) -> {
|
||||
assertThat(propertiesBean.getType()).isEqualTo(NonAnnotatedGenericBean.class);
|
||||
assertThat(propertiesBean.getBindMethod()).isEqualTo(BindMethod.JAVA_BEAN);
|
||||
assertThat(propertiesBean.asBindTarget().getBindMethod()).isEqualTo(BindMethod.JAVA_BEAN);
|
||||
ResolvableType type = propertiesBean.asBindTarget().getType();
|
||||
assertThat(type.resolve()).isEqualTo(NonAnnotatedGenericBean.class);
|
||||
assertThat(type.resolveGeneric(0)).isEqualTo(String.class);
|
||||
|
@ -169,7 +169,7 @@ class ConfigurationPropertiesBeanTests {
|
|||
void getWhenHasFactoryMethodWithoutAnnotationBindsUsingMethodType() throws Throwable {
|
||||
get(AnnotatedGenericBeanConfiguration.class, "annotatedGenericBean", (propertiesBean) -> {
|
||||
assertThat(propertiesBean.getType()).isEqualTo(AnnotatedGenericBean.class);
|
||||
assertThat(propertiesBean.getBindMethod()).isEqualTo(BindMethod.JAVA_BEAN);
|
||||
assertThat(propertiesBean.asBindTarget().getBindMethod()).isEqualTo(BindMethod.JAVA_BEAN);
|
||||
ResolvableType type = propertiesBean.asBindTarget().getType();
|
||||
assertThat(type.resolve()).isEqualTo(AnnotatedGenericBean.class);
|
||||
assertThat(type.resolveGeneric(0)).isEqualTo(String.class);
|
||||
|
@ -180,7 +180,7 @@ class ConfigurationPropertiesBeanTests {
|
|||
void getWhenHasNoFactoryMethodBindsUsingObjectType() throws Throwable {
|
||||
get(AnnotatedGenericComponent.class, "annotatedGenericComponent", (propertiesBean) -> {
|
||||
assertThat(propertiesBean.getType()).isEqualTo(AnnotatedGenericComponent.class);
|
||||
assertThat(propertiesBean.getBindMethod()).isEqualTo(BindMethod.JAVA_BEAN);
|
||||
assertThat(propertiesBean.asBindTarget().getBindMethod()).isEqualTo(BindMethod.JAVA_BEAN);
|
||||
ResolvableType type = propertiesBean.asBindTarget().getType();
|
||||
assertThat(type.resolve()).isEqualTo(AnnotatedGenericComponent.class);
|
||||
assertThat(type.getGeneric(0).resolve()).isNull();
|
||||
|
@ -224,7 +224,7 @@ class ConfigurationPropertiesBeanTests {
|
|||
assertThat(propertiesBean.getName()).isEqualTo("valueObjectBean");
|
||||
assertThat(propertiesBean.getInstance()).isNull();
|
||||
assertThat(propertiesBean.getType()).isEqualTo(ConstructorBindingOnConstructor.class);
|
||||
assertThat(propertiesBean.getBindMethod()).isEqualTo(BindMethod.VALUE_OBJECT);
|
||||
assertThat(propertiesBean.asBindTarget().getBindMethod()).isEqualTo(BindMethod.VALUE_OBJECT);
|
||||
assertThat(propertiesBean.getAnnotation()).isNotNull();
|
||||
Bindable<?> target = propertiesBean.asBindTarget();
|
||||
assertThat(target.getType()).isEqualTo(ResolvableType.forClass(ConstructorBindingOnConstructor.class));
|
||||
|
@ -234,14 +234,13 @@ class ConfigurationPropertiesBeanTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
@Deprecated(since = "3.0.0", forRemoval = true)
|
||||
void forValueObjectWithDeprecatedConstructorBindingAnnotatedClassReturnsBean() {
|
||||
ConfigurationPropertiesBean propertiesBean = ConfigurationPropertiesBean
|
||||
.forValueObject(DeprecatedConstructorBindingOnConstructor.class, "valueObjectBean");
|
||||
assertThat(propertiesBean.getName()).isEqualTo("valueObjectBean");
|
||||
assertThat(propertiesBean.getInstance()).isNull();
|
||||
assertThat(propertiesBean.getType()).isEqualTo(DeprecatedConstructorBindingOnConstructor.class);
|
||||
assertThat(propertiesBean.getBindMethod()).isEqualTo(BindMethod.VALUE_OBJECT);
|
||||
assertThat(propertiesBean.asBindTarget().getBindMethod()).isEqualTo(BindMethod.VALUE_OBJECT);
|
||||
assertThat(propertiesBean.getAnnotation()).isNotNull();
|
||||
Bindable<?> target = propertiesBean.asBindTarget();
|
||||
assertThat(target.getType())
|
||||
|
@ -269,7 +268,7 @@ class ConfigurationPropertiesBeanTests {
|
|||
assertThat(propertiesBean.getName()).isEqualTo("implicitBindingRecord");
|
||||
assertThat(propertiesBean.getInstance()).isNull();
|
||||
assertThat(propertiesBean.getType()).isEqualTo(implicitConstructorBinding);
|
||||
assertThat(propertiesBean.getBindMethod()).isEqualTo(BindMethod.VALUE_OBJECT);
|
||||
assertThat(propertiesBean.asBindTarget().getBindMethod()).isEqualTo(BindMethod.VALUE_OBJECT);
|
||||
assertThat(propertiesBean.getAnnotation()).isNotNull();
|
||||
Bindable<?> target = propertiesBean.asBindTarget();
|
||||
assertThat(target.getType()).isEqualTo(ResolvableType.forClass(implicitConstructorBinding));
|
||||
|
@ -292,64 +291,66 @@ class ConfigurationPropertiesBeanTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
void bindMethodGetWhenNoConstructorBindingReturnsJavaBean() {
|
||||
BindMethod bindType = BindMethod.get(NoConstructorBinding.class);
|
||||
void deduceBindMethodWhenNoConstructorBindingReturnsJavaBean() {
|
||||
BindMethod bindType = ConfigurationPropertiesBean.deduceBindMethod(NoConstructorBinding.class);
|
||||
assertThat(bindType).isEqualTo(BindMethod.JAVA_BEAN);
|
||||
}
|
||||
|
||||
@Test
|
||||
void bindMethodGetWhenConstructorBindingOnConstructorReturnsValueObject() {
|
||||
BindMethod bindType = BindMethod.get(ConstructorBindingOnConstructor.class);
|
||||
void deduceBindMethodWhenConstructorBindingOnConstructorReturnsValueObject() {
|
||||
BindMethod bindType = ConfigurationPropertiesBean.deduceBindMethod(ConstructorBindingOnConstructor.class);
|
||||
assertThat(bindType).isEqualTo(BindMethod.VALUE_OBJECT);
|
||||
}
|
||||
|
||||
@Test
|
||||
void bindMethodGetWhenNoConstructorBindingAnnotationOnSingleParameterizedConstructorReturnsValueObject() {
|
||||
BindMethod bindType = BindMethod.get(ConstructorBindingNoAnnotation.class);
|
||||
void deduceBindMethodWhenNoConstructorBindingAnnotationOnSingleParameterizedConstructorReturnsValueObject() {
|
||||
BindMethod bindType = ConfigurationPropertiesBean.deduceBindMethod(ConstructorBindingNoAnnotation.class);
|
||||
assertThat(bindType).isEqualTo(BindMethod.VALUE_OBJECT);
|
||||
}
|
||||
|
||||
@Test
|
||||
void bindMethodGetWhenConstructorBindingOnMultipleConstructorsThrowsException() {
|
||||
void deduceBindMethodWhenConstructorBindingOnMultipleConstructorsThrowsException() {
|
||||
assertThatIllegalStateException()
|
||||
.isThrownBy(() -> BindMethod.get(ConstructorBindingOnMultipleConstructors.class))
|
||||
.isThrownBy(
|
||||
() -> ConfigurationPropertiesBean.deduceBindMethod(ConstructorBindingOnMultipleConstructors.class))
|
||||
.withMessage(ConstructorBindingOnMultipleConstructors.class.getName()
|
||||
+ " has more than one @ConstructorBinding constructor");
|
||||
}
|
||||
|
||||
@Test
|
||||
void bindMethodGetWithMultipleConstructorsReturnJavaBean() {
|
||||
BindMethod bindType = BindMethod.get(NoConstructorBindingOnMultipleConstructors.class);
|
||||
void deduceBindMethodWithMultipleConstructorsReturnJavaBean() {
|
||||
BindMethod bindType = ConfigurationPropertiesBean
|
||||
.deduceBindMethod(NoConstructorBindingOnMultipleConstructors.class);
|
||||
assertThat(bindType).isEqualTo(BindMethod.JAVA_BEAN);
|
||||
}
|
||||
|
||||
@Test
|
||||
void bindMethodGetWithNoArgConstructorReturnsJavaBean() {
|
||||
BindMethod bindType = BindMethod.get(JavaBeanWithNoArgConstructor.class);
|
||||
void deduceBindMethodWithNoArgConstructorReturnsJavaBean() {
|
||||
BindMethod bindType = ConfigurationPropertiesBean.deduceBindMethod(JavaBeanWithNoArgConstructor.class);
|
||||
assertThat(bindType).isEqualTo(BindMethod.JAVA_BEAN);
|
||||
}
|
||||
|
||||
@Test
|
||||
void bindMethodGetWithSingleArgAutowiredConstructorReturnsJavaBean() {
|
||||
BindMethod bindType = BindMethod.get(JavaBeanWithAutowiredConstructor.class);
|
||||
void deduceBindMethodWithSingleArgAutowiredConstructorReturnsJavaBean() {
|
||||
BindMethod bindType = ConfigurationPropertiesBean.deduceBindMethod(JavaBeanWithAutowiredConstructor.class);
|
||||
assertThat(bindType).isEqualTo(BindMethod.JAVA_BEAN);
|
||||
}
|
||||
|
||||
@Test
|
||||
void constructorBindingAndAutowiredConstructorsShouldThrowException() {
|
||||
assertThatIllegalStateException()
|
||||
.isThrownBy(() -> BindMethod.get(ConstructorBindingAndAutowiredConstructors.class));
|
||||
assertThatIllegalStateException().isThrownBy(
|
||||
() -> ConfigurationPropertiesBean.deduceBindMethod(ConstructorBindingAndAutowiredConstructors.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void innerClassWithSyntheticFieldShouldReturnJavaBean() {
|
||||
BindMethod bindType = BindMethod.get(Inner.class);
|
||||
BindMethod bindType = ConfigurationPropertiesBean.deduceBindMethod(Inner.class);
|
||||
assertThat(bindType).isEqualTo(BindMethod.JAVA_BEAN);
|
||||
}
|
||||
|
||||
@Test
|
||||
void innerClassWithParameterizedConstructorShouldReturnJavaBean() {
|
||||
BindMethod bindType = BindMethod.get(ParameterizedConstructorInner.class);
|
||||
BindMethod bindType = ConfigurationPropertiesBean.deduceBindMethod(ParameterizedConstructorInner.class);
|
||||
assertThat(bindType).isEqualTo(BindMethod.JAVA_BEAN);
|
||||
}
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ import org.junit.jupiter.api.Test;
|
|||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||
import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||
import org.springframework.boot.context.properties.ConfigurationPropertiesBean.BindMethod;
|
||||
import org.springframework.boot.context.properties.bind.BindMethod;
|
||||
import org.springframework.boot.context.properties.scan.combined.c.CombinedConfiguration;
|
||||
import org.springframework.boot.context.properties.scan.combined.d.OtherCombinedConfiguration;
|
||||
import org.springframework.boot.context.properties.scan.valid.ConfigurationPropertiesScanConfiguration;
|
||||
|
|
|
@ -24,7 +24,7 @@ import org.junit.jupiter.api.Test;
|
|||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||
import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||
import org.springframework.boot.context.properties.ConfigurationPropertiesBean.BindMethod;
|
||||
import org.springframework.boot.context.properties.bind.BindMethod;
|
||||
import org.springframework.core.type.AnnotationMetadata;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
|
|
@ -29,6 +29,7 @@ import org.springframework.core.annotation.AnnotationUtils;
|
|||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
|
@ -190,9 +191,64 @@ class BindableTests {
|
|||
assertThat(restricted.hasBindRestriction(BindRestriction.NO_DIRECT_PROPERTY)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenTypeCouldUseJavaBeanOrValueObjectJavaBeanBindingCanBeSpecified() {
|
||||
BindMethod bindMethod = Bindable.of(JavaBeanOrValueObject.class)
|
||||
.withBindMethod(BindMethod.JAVA_BEAN)
|
||||
.getBindMethod();
|
||||
assertThat(bindMethod).isEqualTo(BindMethod.JAVA_BEAN);
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenTypeCouldUseJavaBeanOrValueObjectExistingValueForcesJavaBeanBinding() {
|
||||
BindMethod bindMethod = Bindable.of(JavaBeanOrValueObject.class)
|
||||
.withExistingValue(new JavaBeanOrValueObject("value"))
|
||||
.getBindMethod();
|
||||
assertThat(bindMethod).isEqualTo(BindMethod.JAVA_BEAN);
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenBindingIsValueObjectExistingValueThrowsException() {
|
||||
assertThatIllegalStateException().isThrownBy(() -> Bindable.of(JavaBeanOrValueObject.class)
|
||||
.withBindMethod(BindMethod.VALUE_OBJECT)
|
||||
.withExistingValue(new JavaBeanOrValueObject("value")));
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenBindableHasExistingValueValueObjectBindMethodThrowsException() {
|
||||
assertThatIllegalStateException().isThrownBy(() -> Bindable.of(JavaBeanOrValueObject.class)
|
||||
.withExistingValue(new JavaBeanOrValueObject("value"))
|
||||
.withBindMethod(BindMethod.VALUE_OBJECT));
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenBindableHasSuppliedValueValueObjectBindMethodThrowsException() {
|
||||
assertThatIllegalStateException().isThrownBy(() -> Bindable.of(JavaBeanOrValueObject.class)
|
||||
.withSuppliedValue(() -> new JavaBeanOrValueObject("value"))
|
||||
.withBindMethod(BindMethod.VALUE_OBJECT));
|
||||
}
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@interface TestAnnotation {
|
||||
|
||||
}
|
||||
|
||||
static class JavaBeanOrValueObject {
|
||||
|
||||
private String property;
|
||||
|
||||
JavaBeanOrValueObject(String property) {
|
||||
this.property = property;
|
||||
}
|
||||
|
||||
String getProperty() {
|
||||
return this.property;
|
||||
}
|
||||
|
||||
void setProperty(String property) {
|
||||
this.property = property;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import org.assertj.core.api.Assertions.assertThat
|
|||
import org.junit.jupiter.api.Test
|
||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory
|
||||
import org.springframework.beans.factory.support.RootBeanDefinition
|
||||
import org.springframework.boot.context.properties.bind.BindMethod
|
||||
|
||||
/**
|
||||
* Tests for `ConfigurationPropertiesBeanRegistrar`.
|
||||
|
@ -30,9 +31,8 @@ class KotlinConfigurationPropertiesBeanRegistrarTests {
|
|||
this.registrar.register(BarProperties::class.java)
|
||||
val beanDefinition = this.beanFactory.getBeanDefinition(
|
||||
"bar-org.springframework.boot.context.properties.KotlinConfigurationPropertiesBeanRegistrarTests\$BarProperties")
|
||||
assertThat(beanDefinition.hasAttribute(ConfigurationPropertiesBean.BindMethod::class.java.name)).isTrue()
|
||||
assertThat(beanDefinition.getAttribute(ConfigurationPropertiesBean.BindMethod::class.java.name))
|
||||
.isEqualTo(ConfigurationPropertiesBean.BindMethod.VALUE_OBJECT)
|
||||
assertThat(beanDefinition.hasAttribute(BindMethod::class.java.name)).isTrue()
|
||||
assertThat(beanDefinition.getAttribute(BindMethod::class.java.name)).isEqualTo(BindMethod.VALUE_OBJECT)
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
Loading…
Reference in New Issue