diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/MvcUriComponentsBuilder.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/MvcUriComponentsBuilder.java index c3141a09ba..4cf28d5ef9 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/MvcUriComponentsBuilder.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/MvcUriComponentsBuilder.java @@ -33,6 +33,7 @@ import org.jspecify.annotations.Nullable; import org.springframework.aot.AotDetector; import org.springframework.beans.factory.NoSuchBeanDefinitionException; import org.springframework.beans.factory.config.ConfigurableBeanFactory; +import org.springframework.beans.factory.config.EmbeddedValueResolver; import org.springframework.cglib.core.SpringNamingPolicy; import org.springframework.cglib.proxy.Callback; 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.MethodFilter; import org.springframework.util.StringUtils; -import org.springframework.util.SystemPropertyUtils; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.context.WebApplicationContext; import org.springframework.web.context.request.RequestAttributes; @@ -629,14 +629,13 @@ public class MvcUriComponentsBuilder { } private static String resolveEmbeddedValue(String value) { - if (value.contains(SystemPropertyUtils.PLACEHOLDER_PREFIX)) { - WebApplicationContext webApplicationContext = getWebApplicationContext(); - if (webApplicationContext != null && - webApplicationContext.getAutowireCapableBeanFactory() instanceof ConfigurableBeanFactory cbf) { - String resolvedEmbeddedValue = cbf.resolveEmbeddedValue(value); - if (resolvedEmbeddedValue != null) { - return resolvedEmbeddedValue; - } + WebApplicationContext webApplicationContext = getWebApplicationContext(); + if (webApplicationContext != null && + webApplicationContext.getAutowireCapableBeanFactory() instanceof ConfigurableBeanFactory cbf) { + EmbeddedValueResolver embeddedValueResolver = new EmbeddedValueResolver(cbf); + String resolvedEmbeddedValue = embeddedValueResolver.resolveStringValue(value); + if (resolvedEmbeddedValue != null) { + return resolvedEmbeddedValue; } } return value; diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/MvcUriComponentsBuilderTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/MvcUriComponentsBuilderTests.java index b0ad9fb167..15d28092ff 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/MvcUriComponentsBuilderTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/MvcUriComponentsBuilderTests.java @@ -335,6 +335,22 @@ public class MvcUriComponentsBuilderTests { 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 void fromMethodNameWithAnnotationsOnInterface() { initWebApplicationContext(WebConfig.class); @@ -703,6 +719,11 @@ public class MvcUriComponentsBuilderTests { HttpEntity methodWithConfigurableMapping(@PathVariable String id) { return null; } + + @RequestMapping("/#{systemProperties.customMapping}/{id}/foo") + HttpEntity methodWithConfigurableMappingThroughSpEL(@PathVariable String id) { + return null; + } }