Improve HandlerMethod#resolvedFromHandlerMethod initialization
Ensure the original instance is always the one returned no matter how many times the HandlerMethod is re-created. Make the constructor protected to allow subclasses to re-create the HandlerMethod as the concrete subclass. See gh-34375
This commit is contained in:
parent
174d0e4576
commit
56c4d2d4ca
|
@ -181,9 +181,13 @@ public class HandlerMethod extends AnnotatedMethod {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Re-create HandlerMethod with additional input.
|
* Re-create new HandlerMethod instance that copies the given HandlerMethod
|
||||||
|
* but replaces the handler, and optionally checks for the presence of
|
||||||
|
* validation annotations.
|
||||||
|
* <p>Subclasses can override this to ensure that a HandlerMethod is of the
|
||||||
|
* same type if re-created.
|
||||||
*/
|
*/
|
||||||
private HandlerMethod(HandlerMethod handlerMethod, @Nullable Object handler, boolean initValidateFlags) {
|
protected HandlerMethod(HandlerMethod handlerMethod, @Nullable Object handler, boolean initValidateFlags) {
|
||||||
super(handlerMethod);
|
super(handlerMethod);
|
||||||
this.bean = (handler != null ? handler : handlerMethod.bean);
|
this.bean = (handler != null ? handler : handlerMethod.bean);
|
||||||
this.beanFactory = handlerMethod.beanFactory;
|
this.beanFactory = handlerMethod.beanFactory;
|
||||||
|
@ -197,7 +201,8 @@ public class HandlerMethod extends AnnotatedMethod {
|
||||||
handlerMethod.validateReturnValue);
|
handlerMethod.validateReturnValue);
|
||||||
this.responseStatus = handlerMethod.responseStatus;
|
this.responseStatus = handlerMethod.responseStatus;
|
||||||
this.responseStatusReason = handlerMethod.responseStatusReason;
|
this.responseStatusReason = handlerMethod.responseStatusReason;
|
||||||
this.resolvedFromHandlerMethod = handlerMethod;
|
this.resolvedFromHandlerMethod = (handlerMethod.resolvedFromHandlerMethod != null ?
|
||||||
|
handlerMethod.resolvedFromHandlerMethod : handlerMethod);
|
||||||
this.description = handlerMethod.toString();
|
this.description = handlerMethod.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,7 @@ import jakarta.validation.constraints.NotEmpty;
|
||||||
import jakarta.validation.constraints.Size;
|
import jakarta.validation.constraints.Size;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import org.springframework.context.support.StaticApplicationContext;
|
||||||
import org.springframework.util.ClassUtils;
|
import org.springframework.util.ClassUtils;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
|
||||||
|
@ -79,6 +80,23 @@ class HandlerMethodTests {
|
||||||
assertThat(handlerMethod.createWithResolvedBean()).isSameAs(handlerMethod);
|
assertThat(handlerMethod.createWithResolvedBean()).isSameAs(handlerMethod);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void resolvedFromHandlerMethod() {
|
||||||
|
StaticApplicationContext context = new StaticApplicationContext();
|
||||||
|
context.registerSingleton("myClass", MyClass.class);
|
||||||
|
|
||||||
|
MyClass target = new MyClass();
|
||||||
|
Method method = ClassUtils.getMethod(target.getClass(), "addPerson", (Class<?>[]) null);
|
||||||
|
|
||||||
|
HandlerMethod hm1 = new HandlerMethod("myClass", context.getBeanFactory(), method);
|
||||||
|
HandlerMethod hm2 = hm1.createWithValidateFlags();
|
||||||
|
HandlerMethod hm3 = hm2.createWithResolvedBean();
|
||||||
|
|
||||||
|
assertThat(hm1.getResolvedFromHandlerMethod()).isNull();
|
||||||
|
assertThat(hm2.getResolvedFromHandlerMethod()).isSameAs(hm1);
|
||||||
|
assertThat(hm3.getResolvedFromHandlerMethod()).isSameAs(hm1);
|
||||||
|
}
|
||||||
|
|
||||||
private static void testValidateArgs(Object target, List<String> methodNames, boolean expected) {
|
private static void testValidateArgs(Object target, List<String> methodNames, boolean expected) {
|
||||||
for (String methodName : methodNames) {
|
for (String methodName : methodNames) {
|
||||||
assertThat(getHandlerMethod(target, methodName).shouldValidateArguments()).isEqualTo(expected);
|
assertThat(getHandlerMethod(target, methodName).shouldValidateArguments()).isEqualTo(expected);
|
||||||
|
|
Loading…
Reference in New Issue