Start building against Spring Framework 7.0.0-M8 snapshots

See gh-46620
This commit is contained in:
Phillip Webb 2025-07-31 07:20:47 +01:00
parent 5767b4e4bb
commit 067b4204b3
5 changed files with 34 additions and 25 deletions

View File

@ -37,7 +37,7 @@ class PatternParseFailureAnalyzerTests {
void patternParseFailureQuotesPattern() {
FailureAnalysis failureAnalysis = performAnalysis("/spring/**/framework");
assertThat(failureAnalysis.getDescription())
.contains("Invalid mapping pattern detected:\n" + "/spring/**/framework\n" + " ^");
.contains("Invalid mapping pattern detected:\n" + "/spring/**/framework\n" + " ^");
assertThat(failureAnalysis.getAction())
.contains("Fix this pattern in your application or switch to the legacy parser"
+ " implementation with 'spring.mvc.pathmatch.matching-strategy=ant_path_matcher'.");

View File

@ -19,7 +19,7 @@ mavenVersion=3.9.10
mockitoVersion=5.18.0
nativeBuildToolsVersion=0.11.0
snakeYamlVersion=2.4
springFrameworkVersion=7.0.0-M7
springFrameworkVersion=7.0.0-SNAPSHOT
springFramework60xVersion=6.0.23
tomcatVersion=11.0.9
nullabilityPluginVersion=0.0.2

View File

@ -20,15 +20,16 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter;
import org.springframework.http.converter.xml.AbstractXmlHttpMessageConverter;
import org.springframework.util.ClassUtils;
import org.springframework.util.CollectionUtils;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
@ -64,13 +65,16 @@ public class HttpMessageConverters implements Iterable<HttpMessageConverter<?>>
NON_REPLACING_CONVERTERS = Collections.unmodifiableList(nonReplacingConverters);
}
private static final Map<Class<?>, Class<?>> EQUIVALENT_CONVERTERS;
private static final MultiValueMap<Class<?>, Class<?>> EQUIVALENT_CONVERTERS;
static {
Map<Class<?>, Class<?>> equivalentConverters = new HashMap<>();
MultiValueMap<Class<?>, Class<?>> equivalentConverters = new LinkedMultiValueMap<>();
putIfExists(equivalentConverters, "org.springframework.http.converter.json.JacksonJsonHttpMessageConverter",
"org.springframework.http.converter.json.MappingJackson2HttpMessageConverter",
"org.springframework.http.converter.json.GsonHttpMessageConverter");
putIfExists(equivalentConverters, "org.springframework.http.converter.json.MappingJackson2HttpMessageConverter",
"org.springframework.http.converter.json.GsonHttpMessageConverter");
EQUIVALENT_CONVERTERS = Collections.unmodifiableMap(equivalentConverters);
EQUIVALENT_CONVERTERS = CollectionUtils.unmodifiableMultiValueMap(equivalentConverters);
}
private final List<HttpMessageConverter<?>> converters;
@ -146,8 +150,10 @@ public class HttpMessageConverters implements Iterable<HttpMessageConverter<?>>
if (ClassUtils.isAssignableValue(converterClass, candidate)) {
return true;
}
Class<?> equivalentClass = EQUIVALENT_CONVERTERS.get(converterClass);
return equivalentClass != null && ClassUtils.isAssignableValue(equivalentClass, candidate);
List<Class<?>> equivalentClasses = EQUIVALENT_CONVERTERS.get(converterClass);
return (equivalentClasses != null) && equivalentClasses.stream()
.anyMatch((equivalentClass) -> equivalentClass != null
&& ClassUtils.isAssignableValue(equivalentClass, candidate));
}
private void configurePartConverters(AllEncompassingFormHttpMessageConverter formConverter,
@ -236,12 +242,15 @@ public class HttpMessageConverters implements Iterable<HttpMessageConverter<?>>
}
}
private static void putIfExists(Map<Class<?>, Class<?>> map, String keyClassName, String valueClassName) {
try {
map.put(Class.forName(keyClassName), Class.forName(valueClassName));
}
catch (ClassNotFoundException | NoClassDefFoundError ex) {
// Ignore
private static void putIfExists(MultiValueMap<Class<?>, Class<?>> map, String keyClassName,
String... valueClassNames) {
for (String valueClassName : valueClassNames) {
try {
map.add(Class.forName(keyClassName), Class.forName(valueClassName));
}
catch (ClassNotFoundException | NoClassDefFoundError ex) {
// Ignore
}
}
}

View File

@ -391,9 +391,9 @@ public final class WebFluxAutoConfiguration {
}
@Override
@ConditionalOnMissingBean(name = "mvcApiVersionStrategy")
public @Nullable ApiVersionStrategy mvcApiVersionStrategy() {
return super.mvcApiVersionStrategy();
@ConditionalOnMissingBean(name = "webFluxApiVersionStrategy")
public @Nullable ApiVersionStrategy webFluxApiVersionStrategy() {
return super.webFluxApiVersionStrategy();
}
}

View File

@ -807,7 +807,7 @@ class WebFluxAutoConfigurationTests {
"spring.webflux.apiversion.required=true", "spring.webflux.apiversion.supported=123,456",
"spring.webflux.apiversion.detect-supported=false")
.run((context) -> {
DefaultApiVersionStrategy versionStrategy = context.getBean("mvcApiVersionStrategy",
DefaultApiVersionStrategy versionStrategy = context.getBean("webFluxApiVersionStrategy",
DefaultApiVersionStrategy.class);
MockServerWebExchange request = MockServerWebExchange
.from(MockServerHttpRequest.get("https://example.com"));
@ -826,7 +826,7 @@ class WebFluxAutoConfigurationTests {
.withPropertyValues("spring.webflux.apiversion.use.header=version",
"spring.webflux.apiversion.default=1.0.0")
.run((context) -> {
DefaultApiVersionStrategy versionStrategy = context.getBean("mvcApiVersionStrategy",
DefaultApiVersionStrategy versionStrategy = context.getBean("webFluxApiVersionStrategy",
DefaultApiVersionStrategy.class);
MockServerWebExchange request = MockServerWebExchange
.from(MockServerHttpRequest.get("https://example.com"));
@ -841,7 +841,7 @@ class WebFluxAutoConfigurationTests {
@Test
void apiVersionUseHeaderPropertyIsApplied() {
this.contextRunner.withPropertyValues("spring.webflux.apiversion.use.header=hv").run((context) -> {
DefaultApiVersionStrategy versionStrategy = context.getBean("mvcApiVersionStrategy",
DefaultApiVersionStrategy versionStrategy = context.getBean("webFluxApiVersionStrategy",
DefaultApiVersionStrategy.class);
MockServerWebExchange request = MockServerWebExchange
.from(MockServerHttpRequest.get("https://example.com").header("hv", "123"));
@ -852,7 +852,7 @@ class WebFluxAutoConfigurationTests {
@Test
void apiVersionUseRequestParameterPropertyIsApplied() {
this.contextRunner.withPropertyValues("spring.webflux.apiversion.use.request-parameter=rpv").run((context) -> {
DefaultApiVersionStrategy versionStrategy = context.getBean("mvcApiVersionStrategy",
DefaultApiVersionStrategy versionStrategy = context.getBean("webFluxApiVersionStrategy",
DefaultApiVersionStrategy.class);
MockServerWebExchange request = MockServerWebExchange
.from(MockServerHttpRequest.get("https://example.com?rpv=123"));
@ -863,7 +863,7 @@ class WebFluxAutoConfigurationTests {
@Test
void apiVersionUsePathSegmentPropertyIsApplied() {
this.contextRunner.withPropertyValues("spring.webflux.apiversion.use.path-segment=1").run((context) -> {
DefaultApiVersionStrategy versionStrategy = context.getBean("mvcApiVersionStrategy",
DefaultApiVersionStrategy versionStrategy = context.getBean("webFluxApiVersionStrategy",
DefaultApiVersionStrategy.class);
MockServerWebExchange request = MockServerWebExchange
.from(MockServerHttpRequest.get("https://example.com/test/123"));
@ -876,7 +876,7 @@ class WebFluxAutoConfigurationTests {
this.contextRunner
.withPropertyValues("spring.webflux.apiversion.use.media-type-parameter[application/json]=mtpv")
.run((context) -> {
DefaultApiVersionStrategy versionStrategy = context.getBean("mvcApiVersionStrategy",
DefaultApiVersionStrategy versionStrategy = context.getBean("webFluxApiVersionStrategy",
DefaultApiVersionStrategy.class);
MockServerWebExchange request = MockServerWebExchange
.from(MockServerHttpRequest.get("https://example.com")
@ -888,7 +888,7 @@ class WebFluxAutoConfigurationTests {
@Test
void apiVersionBeansAreInjected() {
this.contextRunner.withUserConfiguration(ApiVersionConfiguration.class).run((context) -> {
DefaultApiVersionStrategy versionStrategy = context.getBean("mvcApiVersionStrategy",
DefaultApiVersionStrategy versionStrategy = context.getBean("webFluxApiVersionStrategy",
DefaultApiVersionStrategy.class);
assertThat(versionStrategy).extracting("versionResolvers")
.asInstanceOf(InstanceOfAssertFactories.LIST)