Merge branch '6.1.x'

# Conflicts:
#	spring-jms/src/main/java/org/springframework/jms/listener/DefaultMessageListenerContainer.java
This commit is contained in:
Juergen Hoeller 2024-02-26 13:42:00 +01:00
commit 4d206f79d0
5 changed files with 40 additions and 19 deletions

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2023 the original author or authors. * Copyright 2002-2024 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -21,6 +21,7 @@ import java.lang.reflect.Method;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.springframework.core.MethodParameter;
import org.springframework.core.ResolvableType; import org.springframework.core.ResolvableType;
import org.springframework.core.convert.TypeDescriptor; import org.springframework.core.convert.TypeDescriptor;
import org.springframework.lang.Nullable; import org.springframework.lang.Nullable;
@ -283,16 +284,25 @@ public class BeanWrapperImpl extends AbstractNestablePropertyAccessor implements
@Override @Override
public boolean setValueFallbackIfPossible(@Nullable Object value) { public boolean setValueFallbackIfPossible(@Nullable Object value) {
Method writeMethod = this.pd.getWriteMethodFallback(value != null ? value.getClass() : null); try {
if (writeMethod != null) { Method writeMethod = this.pd.getWriteMethodFallback(value != null ? value.getClass() : null);
ReflectionUtils.makeAccessible(writeMethod); if (writeMethod == null) {
try { writeMethod = this.pd.getUniqueWriteMethodFallback();
if (writeMethod != null) {
// Conversion necessary as we would otherwise have received the method
// from the type-matching getWriteMethodFallback call above already
value = convertForProperty(this.pd.getName(), null, value,
new TypeDescriptor(new MethodParameter(writeMethod, 0)));
}
}
if (writeMethod != null) {
ReflectionUtils.makeAccessible(writeMethod);
writeMethod.invoke(getWrappedInstance(), value); writeMethod.invoke(getWrappedInstance(), value);
return true; return true;
} }
catch (Exception ex) { }
LogFactory.getLog(BeanPropertyHandler.class).debug("Write method fallback failed", ex); catch (Exception ex) {
} LogFactory.getLog(BeanPropertyHandler.class).debug("Write method fallback failed", ex);
} }
return false; return false;
} }

View File

@ -171,6 +171,14 @@ final class GenericTypeAwarePropertyDescriptor extends PropertyDescriptor {
return null; return null;
} }
@Nullable
public Method getUniqueWriteMethodFallback() {
if (this.ambiguousWriteMethods != null && this.ambiguousWriteMethods.size() == 1) {
return this.ambiguousWriteMethods.iterator().next();
}
return null;
}
public boolean hasUniqueWriteMethod() { public boolean hasUniqueWriteMethod() {
return (this.writeMethod != null && this.ambiguousWriteMethods == null); return (this.writeMethod != null && this.ambiguousWriteMethods == null);
} }

View File

@ -1325,6 +1325,11 @@ class DefaultListableBeanFactoryTests {
rbd.getPropertyValues().add("value", Duration.ofSeconds(1000)); rbd.getPropertyValues().add("value", Duration.ofSeconds(1000));
lbf.registerBeanDefinition("overloaded", rbd); lbf.registerBeanDefinition("overloaded", rbd);
assertThat(lbf.getBean(SetterOverload.class).getObject()).isEqualTo("1000s"); assertThat(lbf.getBean(SetterOverload.class).getObject()).isEqualTo("1000s");
rbd = new RootBeanDefinition(SetterOverload.class);
rbd.getPropertyValues().add("value", "1000");
lbf.registerBeanDefinition("overloaded", rbd);
assertThat(lbf.getBean(SetterOverload.class).getObject()).isEqualTo("1000i");
} }
@Test @Test
@ -3382,13 +3387,13 @@ class DefaultListableBeanFactoryTests {
return this.value; return this.value;
} }
public void setValue(int length) {
this.value = length + "i";
}
public void setValue(Duration duration) { public void setValue(Duration duration) {
this.value = duration.getSeconds() + "s"; this.value = duration.getSeconds() + "s";
} }
public void setValue(int length) {
this.value = length + "i";
}
} }

View File

@ -2547,23 +2547,21 @@ class AutowiredAnnotationBeanPostProcessorTests {
assertThat(mixedOptionalInjectionBean.nullableBean).isNull(); assertThat(mixedOptionalInjectionBean.nullableBean).isNull();
} }
private <E extends UnsatisfiedDependencyException> Consumer<E> methodParameterDeclaredOn(
Class<?> expected) { private <E extends UnsatisfiedDependencyException> Consumer<E> methodParameterDeclaredOn(Class<?> expected) {
return declaredOn( return declaredOn(
injectionPoint -> injectionPoint.getMethodParameter().getDeclaringClass(), injectionPoint -> injectionPoint.getMethodParameter().getDeclaringClass(),
expected); expected);
} }
private <E extends UnsatisfiedDependencyException> Consumer<E> fieldDeclaredOn( private <E extends UnsatisfiedDependencyException> Consumer<E> fieldDeclaredOn(Class<?> expected) {
Class<?> expected) {
return declaredOn( return declaredOn(
injectionPoint -> injectionPoint.getField().getDeclaringClass(), injectionPoint -> injectionPoint.getField().getDeclaringClass(),
expected); expected);
} }
private <E extends UnsatisfiedDependencyException> Consumer<E> declaredOn( private <E extends UnsatisfiedDependencyException> Consumer<E> declaredOn(
Function<InjectionPoint, Class<?>> declaringClassExtractor, Function<InjectionPoint, Class<?>> declaringClassExtractor, Class<?> expected) {
Class<?> expected) {
return ex -> { return ex -> {
InjectionPoint injectionPoint = ex.getInjectionPoint(); InjectionPoint injectionPoint = ex.getInjectionPoint();
Class<?> declaringClass = declaringClassExtractor.apply(injectionPoint); Class<?> declaringClass = declaringClassExtractor.apply(injectionPoint);

View File

@ -992,7 +992,7 @@ public class DefaultMessageListenerContainer extends AbstractPollingMessageListe
} }
/** /**
* Used to determine whether this listener container currently has more * Called to determine whether this listener container currently has more
* than one idle instance among its scheduled invokers. * than one idle instance among its scheduled invokers.
*/ */
private int getIdleInvokerCount() { private int getIdleInvokerCount() {