Skip to content

Commit 56c4d2d

Browse files
committed
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 spring-projectsgh-34375
1 parent 174d0e4 commit 56c4d2d

File tree

2 files changed

+26
-3
lines changed

2 files changed

+26
-3
lines changed

spring-web/src/main/java/org/springframework/web/method/HandlerMethod.java

+8-3
Original file line numberDiff line numberDiff line change
@@ -181,9 +181,13 @@ protected HandlerMethod(HandlerMethod handlerMethod) {
181181
}
182182

183183
/**
184-
* Re-create HandlerMethod with additional input.
184+
* Re-create new HandlerMethod instance that copies the given HandlerMethod
185+
* but replaces the handler, and optionally checks for the presence of
186+
* validation annotations.
187+
* <p>Subclasses can override this to ensure that a HandlerMethod is of the
188+
* same type if re-created.
185189
*/
186-
private HandlerMethod(HandlerMethod handlerMethod, @Nullable Object handler, boolean initValidateFlags) {
190+
protected HandlerMethod(HandlerMethod handlerMethod, @Nullable Object handler, boolean initValidateFlags) {
187191
super(handlerMethod);
188192
this.bean = (handler != null ? handler : handlerMethod.bean);
189193
this.beanFactory = handlerMethod.beanFactory;
@@ -197,7 +201,8 @@ private HandlerMethod(HandlerMethod handlerMethod, @Nullable Object handler, boo
197201
handlerMethod.validateReturnValue);
198202
this.responseStatus = handlerMethod.responseStatus;
199203
this.responseStatusReason = handlerMethod.responseStatusReason;
200-
this.resolvedFromHandlerMethod = handlerMethod;
204+
this.resolvedFromHandlerMethod = (handlerMethod.resolvedFromHandlerMethod != null ?
205+
handlerMethod.resolvedFromHandlerMethod : handlerMethod);
201206
this.description = handlerMethod.toString();
202207
}
203208

spring-web/src/test/java/org/springframework/web/method/HandlerMethodTests.java

+18
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import jakarta.validation.constraints.Size;
2626
import org.junit.jupiter.api.Test;
2727

28+
import org.springframework.context.support.StaticApplicationContext;
2829
import org.springframework.util.ClassUtils;
2930
import org.springframework.validation.annotation.Validated;
3031

@@ -79,6 +80,23 @@ void createWithResolvedBeanSameInstance() {
7980
assertThat(handlerMethod.createWithResolvedBean()).isSameAs(handlerMethod);
8081
}
8182

83+
@Test
84+
void resolvedFromHandlerMethod() {
85+
StaticApplicationContext context = new StaticApplicationContext();
86+
context.registerSingleton("myClass", MyClass.class);
87+
88+
MyClass target = new MyClass();
89+
Method method = ClassUtils.getMethod(target.getClass(), "addPerson", (Class<?>[]) null);
90+
91+
HandlerMethod hm1 = new HandlerMethod("myClass", context.getBeanFactory(), method);
92+
HandlerMethod hm2 = hm1.createWithValidateFlags();
93+
HandlerMethod hm3 = hm2.createWithResolvedBean();
94+
95+
assertThat(hm1.getResolvedFromHandlerMethod()).isNull();
96+
assertThat(hm2.getResolvedFromHandlerMethod()).isSameAs(hm1);
97+
assertThat(hm3.getResolvedFromHandlerMethod()).isSameAs(hm1);
98+
}
99+
82100
private static void testValidateArgs(Object target, List<String> methodNames, boolean expected) {
83101
for (String methodName : methodNames) {
84102
assertThat(getHandlerMethod(target, methodName).shouldValidateArguments()).isEqualTo(expected);

0 commit comments

Comments
 (0)