Use EmbeddedValueResolver to resolve embedded value in MvcUriComponentsBuilder

Signed-off-by: 秦利斌 <68638598+Allan-QLB@users.noreply.github.com>
This commit is contained in:
秦利斌 2025-08-19 15:41:07 +08:00
parent 3dc2aa79a4
commit 42f475ba07
2 changed files with 29 additions and 9 deletions

View File

@ -33,6 +33,7 @@ import org.jspecify.annotations.Nullable;
import org.springframework.aot.AotDetector; import org.springframework.aot.AotDetector;
import org.springframework.beans.factory.NoSuchBeanDefinitionException; import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.config.ConfigurableBeanFactory; import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.beans.factory.config.EmbeddedValueResolver;
import org.springframework.cglib.core.SpringNamingPolicy; import org.springframework.cglib.core.SpringNamingPolicy;
import org.springframework.cglib.proxy.Callback; import org.springframework.cglib.proxy.Callback;
import org.springframework.cglib.proxy.Enhancer; import org.springframework.cglib.proxy.Enhancer;
@ -54,7 +55,6 @@ import org.springframework.util.PathMatcher;
import org.springframework.util.ReflectionUtils; import org.springframework.util.ReflectionUtils;
import org.springframework.util.ReflectionUtils.MethodFilter; import org.springframework.util.ReflectionUtils.MethodFilter;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import org.springframework.util.SystemPropertyUtils;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.context.WebApplicationContext; import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.request.RequestAttributes; import org.springframework.web.context.request.RequestAttributes;
@ -629,14 +629,13 @@ public class MvcUriComponentsBuilder {
} }
private static String resolveEmbeddedValue(String value) { private static String resolveEmbeddedValue(String value) {
if (value.contains(SystemPropertyUtils.PLACEHOLDER_PREFIX)) { WebApplicationContext webApplicationContext = getWebApplicationContext();
WebApplicationContext webApplicationContext = getWebApplicationContext(); if (webApplicationContext != null &&
if (webApplicationContext != null && webApplicationContext.getAutowireCapableBeanFactory() instanceof ConfigurableBeanFactory cbf) {
webApplicationContext.getAutowireCapableBeanFactory() instanceof ConfigurableBeanFactory cbf) { EmbeddedValueResolver embeddedValueResolver = new EmbeddedValueResolver(cbf);
String resolvedEmbeddedValue = cbf.resolveEmbeddedValue(value); String resolvedEmbeddedValue = embeddedValueResolver.resolveStringValue(value);
if (resolvedEmbeddedValue != null) { if (resolvedEmbeddedValue != null) {
return resolvedEmbeddedValue; return resolvedEmbeddedValue;
}
} }
} }
return value; return value;

View File

@ -335,6 +335,22 @@ public class MvcUriComponentsBuilderTests {
assertThat(uriComponents.toUriString()).isEqualTo("http://localhost/something/custom/1/foo"); assertThat(uriComponents.toUriString()).isEqualTo("http://localhost/something/custom/1/foo");
} }
@Test
void fromMethodNameConfigurablePathSpEL() {
try {
System.setProperty("customMapping", "custom");
StandardEnvironment environment = new StandardEnvironment();
initWebApplicationContext(WebConfig.class, environment);
UriComponents uriComponents = fromMethodName(ControllerWithMethods.class,
"methodWithConfigurableMappingThroughSpEL", "1").build();
assertThat(uriComponents.toUriString()).isEqualTo("http://localhost/something/custom/1/foo");
}
finally {
System.clearProperty("customMapping");
}
}
@Test @Test
void fromMethodNameWithAnnotationsOnInterface() { void fromMethodNameWithAnnotationsOnInterface() {
initWebApplicationContext(WebConfig.class); initWebApplicationContext(WebConfig.class);
@ -703,6 +719,11 @@ public class MvcUriComponentsBuilderTests {
HttpEntity<Void> methodWithConfigurableMapping(@PathVariable String id) { HttpEntity<Void> methodWithConfigurableMapping(@PathVariable String id) {
return null; return null;
} }
@RequestMapping("/#{systemProperties.customMapping}/{id}/foo")
HttpEntity<Void> methodWithConfigurableMappingThroughSpEL(@PathVariable String id) {
return null;
}
} }