Revise contribution
This commit reverts changes to AbstractCacheManager since iterating over the caches in a for-loop and a stream is duplicated effort. This commit reverts changes to DefaultRenderingResponseBuilder, RouterFunctions, and OriginHandshakeInterceptor since order matters for those use cases: they were originally based on the semantics of LinkedHashSet or LinkedHashMap; whereas, Set.copyOf() and Map.copyOf() do not provide any guarantees regarding ordering. This commit also applies analogous changes to "sibling" implementations across Servlet mocks as well as Web MVC and WebFlux. See gh-29321
This commit is contained in:
parent
ba136dcf40
commit
95f3337bb5
|
@ -22,7 +22,6 @@ import java.util.LinkedHashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.ConcurrentMap;
|
import java.util.concurrent.ConcurrentMap;
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
import org.springframework.beans.factory.InitializingBean;
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
import org.springframework.cache.Cache;
|
import org.springframework.cache.Cache;
|
||||||
|
@ -65,13 +64,13 @@ public abstract class AbstractCacheManager implements CacheManager, Initializing
|
||||||
synchronized (this.cacheMap) {
|
synchronized (this.cacheMap) {
|
||||||
this.cacheNames = Collections.emptySet();
|
this.cacheNames = Collections.emptySet();
|
||||||
this.cacheMap.clear();
|
this.cacheMap.clear();
|
||||||
|
Set<String> cacheNames = new LinkedHashSet<>(caches.size());
|
||||||
for (Cache cache : caches) {
|
for (Cache cache : caches) {
|
||||||
String name = cache.getName();
|
String name = cache.getName();
|
||||||
this.cacheMap.put(name, decorateCache(cache));
|
this.cacheMap.put(name, decorateCache(cache));
|
||||||
|
cacheNames.add(name);
|
||||||
}
|
}
|
||||||
this.cacheNames = caches.stream()
|
this.cacheNames = Collections.unmodifiableSet(cacheNames);
|
||||||
.map(Cache::getName)
|
|
||||||
.collect(Collectors.toUnmodifiableSet());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2021 the original author or authors.
|
* Copyright 2002-2022 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2021 the original author or authors.
|
* Copyright 2002-2022 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2021 the original author or authors.
|
* Copyright 2002-2022 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -16,7 +16,6 @@
|
||||||
|
|
||||||
package org.springframework.web.testfixture.servlet;
|
package org.springframework.web.testfixture.servlet;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
|
@ -61,11 +60,7 @@ class HeaderValueHolder {
|
||||||
}
|
}
|
||||||
|
|
||||||
List<String> getStringValues() {
|
List<String> getStringValues() {
|
||||||
List<String> stringList = new ArrayList<>(this.values.size());
|
return this.values.stream().map(Object::toString).toList();
|
||||||
for (Object value : this.values) {
|
|
||||||
stringList.add(value.toString());
|
|
||||||
}
|
|
||||||
return Collections.unmodifiableList(stringList);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2019 the original author or authors.
|
* Copyright 2002-2022 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -81,12 +81,8 @@ final class DefaultExchangeStrategiesBuilder implements ExchangeStrategies.Build
|
||||||
|
|
||||||
public DefaultExchangeStrategies(ClientCodecConfigurer codecConfigurer) {
|
public DefaultExchangeStrategies(ClientCodecConfigurer codecConfigurer) {
|
||||||
this.codecConfigurer = codecConfigurer;
|
this.codecConfigurer = codecConfigurer;
|
||||||
this.readers = unmodifiableCopy(this.codecConfigurer.getReaders());
|
this.readers = List.copyOf(this.codecConfigurer.getReaders());
|
||||||
this.writers = unmodifiableCopy(this.codecConfigurer.getWriters());
|
this.writers = List.copyOf(this.codecConfigurer.getWriters());
|
||||||
}
|
|
||||||
|
|
||||||
private static <T> List<T> unmodifiableCopy(List<? extends T> list) {
|
|
||||||
return List.copyOf(list);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2018 the original author or authors.
|
* Copyright 2002-2022 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -125,18 +125,14 @@ class DefaultHandlerStrategiesBuilder implements HandlerStrategies.Builder {
|
||||||
List<WebExceptionHandler> exceptionHandlers,
|
List<WebExceptionHandler> exceptionHandlers,
|
||||||
LocaleContextResolver localeContextResolver) {
|
LocaleContextResolver localeContextResolver) {
|
||||||
|
|
||||||
this.messageReaders = unmodifiableCopy(messageReaders);
|
this.messageReaders = List.copyOf(messageReaders);
|
||||||
this.messageWriters = unmodifiableCopy(messageWriters);
|
this.messageWriters = List.copyOf(messageWriters);
|
||||||
this.viewResolvers = unmodifiableCopy(viewResolvers);
|
this.viewResolvers = List.copyOf(viewResolvers);
|
||||||
this.webFilters = unmodifiableCopy(webFilters);
|
this.webFilters = List.copyOf(webFilters);
|
||||||
this.exceptionHandlers = unmodifiableCopy(exceptionHandlers);
|
this.exceptionHandlers = List.copyOf(exceptionHandlers);
|
||||||
this.localeContextResolver = localeContextResolver;
|
this.localeContextResolver = localeContextResolver;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static <T> List<T> unmodifiableCopy(List<? extends T> list) {
|
|
||||||
return List.copyOf(list);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<HttpMessageReader<?>> messageReaders() {
|
public List<HttpMessageReader<?>> messageReaders() {
|
||||||
return this.messageReaders;
|
return this.messageReaders;
|
||||||
|
|
|
@ -171,7 +171,7 @@ final class DefaultRenderingResponseBuilder implements RenderingResponse.Builder
|
||||||
|
|
||||||
super(statusCode, headers, cookies, Collections.emptyMap());
|
super(statusCode, headers, cookies, Collections.emptyMap());
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.model = Map.copyOf(model);
|
this.model = Collections.unmodifiableMap(new LinkedHashMap<>(model));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2020 the original author or authors.
|
* Copyright 2002-2022 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|
|
@ -1175,7 +1175,7 @@ public abstract class RouterFunctions {
|
||||||
return Collections.emptyMap();
|
return Collections.emptyMap();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return Map.copyOf(attributes);
|
return Collections.unmodifiableMap(new LinkedHashMap<>(attributes));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -95,7 +95,7 @@ class DefaultServerRequest implements ServerRequest {
|
||||||
|
|
||||||
public DefaultServerRequest(HttpServletRequest servletRequest, List<HttpMessageConverter<?>> messageConverters) {
|
public DefaultServerRequest(HttpServletRequest servletRequest, List<HttpMessageConverter<?>> messageConverters) {
|
||||||
this.serverHttpRequest = new ServletServerHttpRequest(servletRequest);
|
this.serverHttpRequest = new ServletServerHttpRequest(servletRequest);
|
||||||
this.messageConverters = Collections.unmodifiableList(new ArrayList<>(messageConverters));
|
this.messageConverters = List.copyOf(messageConverters);
|
||||||
|
|
||||||
this.headers = new DefaultRequestHeaders(this.serverHttpRequest.getHeaders());
|
this.headers = new DefaultRequestHeaders(this.serverHttpRequest.getHeaders());
|
||||||
this.params = CollectionUtils.toMultiValueMap(new ServletParametersMap(servletRequest));
|
this.params = CollectionUtils.toMultiValueMap(new ServletParametersMap(servletRequest));
|
||||||
|
|
|
@ -147,9 +147,8 @@ public abstract class AbstractHandlerMethodMapping<T> extends AbstractHandlerMap
|
||||||
public Map<T, HandlerMethod> getHandlerMethods() {
|
public Map<T, HandlerMethod> getHandlerMethods() {
|
||||||
this.mappingRegistry.acquireReadLock();
|
this.mappingRegistry.acquireReadLock();
|
||||||
try {
|
try {
|
||||||
return Collections.unmodifiableMap(
|
return this.mappingRegistry.getRegistrations().entrySet().stream()
|
||||||
this.mappingRegistry.getRegistrations().entrySet().stream()
|
.collect(Collectors.toUnmodifiableMap(Map.Entry::getKey, entry -> entry.getValue().handlerMethod));
|
||||||
.collect(Collectors.toMap(Map.Entry::getKey, entry -> entry.getValue().handlerMethod)));
|
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
this.mappingRegistry.releaseReadLock();
|
this.mappingRegistry.releaseReadLock();
|
||||||
|
|
|
@ -19,9 +19,9 @@ package org.springframework.web.socket.server.support;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.LinkedHashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
@ -95,8 +95,9 @@ public class OriginHandshakeInterceptor implements HandshakeInterceptor {
|
||||||
* @since 4.1.5
|
* @since 4.1.5
|
||||||
*/
|
*/
|
||||||
public Collection<String> getAllowedOrigins() {
|
public Collection<String> getAllowedOrigins() {
|
||||||
return (CollectionUtils.isEmpty(this.corsConfiguration.getAllowedOrigins()) ? Collections.emptySet() :
|
List<String> allowedOrigins = this.corsConfiguration.getAllowedOrigins();
|
||||||
Set.copyOf(this.corsConfiguration.getAllowedOrigins()));
|
return (CollectionUtils.isEmpty(allowedOrigins) ? Collections.emptySet() :
|
||||||
|
Collections.unmodifiableSet(new LinkedHashSet<>(allowedOrigins)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -118,8 +119,9 @@ public class OriginHandshakeInterceptor implements HandshakeInterceptor {
|
||||||
* @since 5.3.2
|
* @since 5.3.2
|
||||||
*/
|
*/
|
||||||
public Collection<String> getAllowedOriginPatterns() {
|
public Collection<String> getAllowedOriginPatterns() {
|
||||||
return (CollectionUtils.isEmpty(this.corsConfiguration.getAllowedOriginPatterns()) ? Collections.emptySet() :
|
List<String> allowedOriginPatterns = this.corsConfiguration.getAllowedOriginPatterns();
|
||||||
Set.copyOf(this.corsConfiguration.getAllowedOriginPatterns()));
|
return (CollectionUtils.isEmpty(allowedOriginPatterns) ? Collections.emptySet() :
|
||||||
|
Collections.unmodifiableSet(new LinkedHashSet<>(allowedOriginPatterns)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2018 the original author or authors.
|
* Copyright 2002-2022 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -49,6 +49,7 @@ public enum TransportType {
|
||||||
private static final Map<String, TransportType> TRANSPORT_TYPES =
|
private static final Map<String, TransportType> TRANSPORT_TYPES =
|
||||||
Arrays.stream(values()).collect(Collectors.toUnmodifiableMap(type -> type.value, type -> type));
|
Arrays.stream(values()).collect(Collectors.toUnmodifiableMap(type -> type.value, type -> type));
|
||||||
|
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public static TransportType fromValue(String value) {
|
public static TransportType fromValue(String value) {
|
||||||
return TRANSPORT_TYPES.get(value);
|
return TRANSPORT_TYPES.get(value);
|
||||||
|
|
Loading…
Reference in New Issue