From 96a4e1150e608a66998988f5d4903297ef11e977 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Fri, 7 Aug 2020 12:59:41 +0200 Subject: [PATCH 1/5] Avoid unnecessary computation of cleaned URL Closes gh-25531 --- .../springframework/core/io/UrlResource.java | 33 +++++++++++++------ 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/spring-core/src/main/java/org/springframework/core/io/UrlResource.java b/spring-core/src/main/java/org/springframework/core/io/UrlResource.java index b989384a019..3f1dcc05ffe 100644 --- a/spring-core/src/main/java/org/springframework/core/io/UrlResource.java +++ b/spring-core/src/main/java/org/springframework/core/io/UrlResource.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2020 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -56,7 +56,8 @@ public class UrlResource extends AbstractFileResolvingResource { /** * Cleaned URL (with normalized path), used for comparisons. */ - private final URL cleanedUrl; + @Nullable + private volatile URL cleanedUrl; /** @@ -69,7 +70,6 @@ public class UrlResource extends AbstractFileResolvingResource { Assert.notNull(uri, "URI must not be null"); this.uri = uri; this.url = uri.toURL(); - this.cleanedUrl = getCleanedUrl(this.url, uri.toString()); } /** @@ -78,9 +78,8 @@ public class UrlResource extends AbstractFileResolvingResource { */ public UrlResource(URL url) { Assert.notNull(url, "URL must not be null"); - this.url = url; - this.cleanedUrl = getCleanedUrl(this.url, url.toString()); this.uri = null; + this.url = url; } /** @@ -127,7 +126,6 @@ public class UrlResource extends AbstractFileResolvingResource { try { this.uri = new URI(protocol, location, fragment); this.url = this.uri.toURL(); - this.cleanedUrl = getCleanedUrl(this.url, this.uri.toString()); } catch (URISyntaxException ex) { MalformedURLException exToThrow = new MalformedURLException(ex.getMessage()); @@ -144,7 +142,7 @@ public class UrlResource extends AbstractFileResolvingResource { * @return the cleaned URL (possibly the original URL as-is) * @see org.springframework.util.StringUtils#cleanPath */ - private URL getCleanedUrl(URL originalUrl, String originalPath) { + private static URL getCleanedUrl(URL originalUrl, String originalPath) { String cleanedPath = StringUtils.cleanPath(originalPath); if (!cleanedPath.equals(originalPath)) { try { @@ -157,6 +155,21 @@ public class UrlResource extends AbstractFileResolvingResource { return originalUrl; } + /** + * Lazily determine a cleaned URL for the given original URL. + * @see #getCleanedUrl(URL, String) + */ + private URL getCleanedUrl() { + URL cleanedUrl = this.cleanedUrl; + if (cleanedUrl != null) { + return cleanedUrl; + } + cleanedUrl = getCleanedUrl(this.url, (this.uri != null ? this.uri : this.url).toString()); + this.cleanedUrl = cleanedUrl; + return cleanedUrl; + } + + /** * This implementation opens an InputStream for the given URL. *

It sets the {@code useCaches} flag to {@code false}, @@ -262,7 +275,7 @@ public class UrlResource extends AbstractFileResolvingResource { */ @Override public String getFilename() { - return StringUtils.getFilename(this.cleanedUrl.getPath()); + return StringUtils.getFilename(getCleanedUrl().getPath()); } /** @@ -280,7 +293,7 @@ public class UrlResource extends AbstractFileResolvingResource { @Override public boolean equals(@Nullable Object other) { return (this == other || (other instanceof UrlResource && - this.cleanedUrl.equals(((UrlResource) other).cleanedUrl))); + getCleanedUrl().equals(((UrlResource) other).getCleanedUrl()))); } /** @@ -288,7 +301,7 @@ public class UrlResource extends AbstractFileResolvingResource { */ @Override public int hashCode() { - return this.cleanedUrl.hashCode(); + return getCleanedUrl().hashCode(); } } From 94eee6a32ae249da0d8fdaf7f6459c2909b26daa Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Fri, 7 Aug 2020 13:00:35 +0200 Subject: [PATCH 2/5] Provide access to AbstractRoutingDataSource's resolved target DataSources Closes gh-25544 --- .../lookup/AbstractRoutingDataSource.java | 26 ++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/lookup/AbstractRoutingDataSource.java b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/lookup/AbstractRoutingDataSource.java index b89bb1abeb8..88669594b10 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/lookup/AbstractRoutingDataSource.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/lookup/AbstractRoutingDataSource.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2020 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,6 +18,7 @@ package org.springframework.jdbc.datasource.lookup; import java.sql.Connection; import java.sql.SQLException; +import java.util.Collections; import java.util.HashMap; import java.util.Map; @@ -164,6 +165,29 @@ public abstract class AbstractRoutingDataSource extends AbstractDataSource imple } } + /** + * Return the resolved target DataSources that this router manages. + * @return an unmodifiable map of resolved lookup keys and DataSources + * @throws IllegalStateException if the target DataSources are not resolved yet + * @since 5.2.9 + * @see #setTargetDataSources + */ + public Map getResolvedDataSources() { + Assert.state(this.resolvedDataSources != null, "DataSources not resolved yet - call afterPropertiesSet"); + return Collections.unmodifiableMap(this.resolvedDataSources); + } + + /** + * Return the resolved default target DataSource, if any. + * @return the default DataSource, or {@code null} if none or not resolved yet + * @since 5.2.9 + * @see #setDefaultTargetDataSource + */ + @Nullable + public DataSource getResolvedDefaultDataSource() { + return this.resolvedDefaultDataSource; + } + @Override public Connection getConnection() throws SQLException { From 8dd285f877fcf1e2f041cd4d914ecc5696920e95 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Fri, 7 Aug 2020 13:02:43 +0200 Subject: [PATCH 3/5] Polishing --- .../support/DefaultListableBeanFactory.java | 10 ++-- .../support/AbstractValueAdaptingCache.java | 6 +-- .../core/io/FileUrlResource.java | 4 +- .../springframework/util/MimeTypeUtils.java | 2 +- ...SocketRequesterMethodArgumentResolver.java | 4 +- ...stenceExceptionTranslationInterceptor.java | 12 ++--- .../org/springframework/http/MediaType.java | 3 +- .../bind/support/WebExchangeDataBinder.java | 4 +- .../bind/support/WebRequestDataBinder.java | 8 +-- .../PathVariableMethodArgumentResolver.java | 4 +- .../web/servlet/HandlerExecutionChain.java | 20 ++++++-- .../handler/AbstractHandlerMapping.java | 49 ++++++++++--------- .../servlet/i18n/CookieLocaleResolver.java | 3 +- 13 files changed, 68 insertions(+), 61 deletions(-) diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java index 5576a31fe09..d2121b23b97 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java @@ -96,8 +96,7 @@ import org.springframework.util.StringUtils; * operating on pre-resolved bean definition metadata objects. * *

Note that readers for specific bean definition formats are typically - * implemented separately rather than as bean factory subclasses: - * see for example {@link PropertiesBeanDefinitionReader} and + * implemented separately rather than as bean factory subclasses: see for example * {@link org.springframework.beans.factory.xml.XmlBeanDefinitionReader}. * *

For an alternative implementation of the @@ -184,7 +183,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto private volatile String[] frozenBeanDefinitionNames; /** Whether bean definition metadata may be cached for all beans. */ - private volatile boolean configurationFrozen = false; + private volatile boolean configurationFrozen; /** @@ -355,12 +354,11 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto } @Override - public ObjectProvider getBeanProvider(Class requiredType) throws BeansException { + public ObjectProvider getBeanProvider(Class requiredType) { Assert.notNull(requiredType, "Required type must not be null"); return getBeanProvider(ResolvableType.forRawClass(requiredType)); } - @SuppressWarnings("unchecked") @Override public ObjectProvider getBeanProvider(ResolvableType requiredType) { return new BeanObjectProvider() { @@ -390,12 +388,14 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto public T getIfUnique() throws BeansException { return resolveBean(requiredType, null, true); } + @SuppressWarnings("unchecked") @Override public Stream stream() { return Arrays.stream(getBeanNamesForTypedStream(requiredType)) .map(name -> (T) getBean(name)) .filter(bean -> !(bean instanceof NullBean)); } + @SuppressWarnings("unchecked") @Override public Stream orderedStream() { String[] beanNames = getBeanNamesForTypedStream(requiredType); diff --git a/spring-context/src/main/java/org/springframework/cache/support/AbstractValueAdaptingCache.java b/spring-context/src/main/java/org/springframework/cache/support/AbstractValueAdaptingCache.java index 96091db9c3c..28beb6da531 100644 --- a/spring-context/src/main/java/org/springframework/cache/support/AbstractValueAdaptingCache.java +++ b/spring-context/src/main/java/org/springframework/cache/support/AbstractValueAdaptingCache.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2020 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -55,8 +55,7 @@ public abstract class AbstractValueAdaptingCache implements Cache { @Override @Nullable public ValueWrapper get(Object key) { - Object value = lookup(key); - return toValueWrapper(value); + return toValueWrapper(lookup(key)); } @Override @@ -123,5 +122,4 @@ public abstract class AbstractValueAdaptingCache implements Cache { return (storeValue != null ? new SimpleValueWrapper(fromStoreValue(storeValue)) : null); } - } diff --git a/spring-core/src/main/java/org/springframework/core/io/FileUrlResource.java b/spring-core/src/main/java/org/springframework/core/io/FileUrlResource.java index 99f0d95874d..4e1b0fa8093 100644 --- a/spring-core/src/main/java/org/springframework/core/io/FileUrlResource.java +++ b/spring-core/src/main/java/org/springframework/core/io/FileUrlResource.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2020 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -52,7 +52,7 @@ public class FileUrlResource extends UrlResource implements WritableResource { /** * Create a new {@code FileUrlResource} based on the given URL object. *

Note that this does not enforce "file" as URL protocol. If a protocol - * is known to be resolvable to a file, + * is known to be resolvable to a file, it is acceptable for this purpose. * @param url a URL * @see ResourceUtils#isFileURL(URL) * @see #getFile() diff --git a/spring-core/src/main/java/org/springframework/util/MimeTypeUtils.java b/spring-core/src/main/java/org/springframework/util/MimeTypeUtils.java index 16ce26bf961..846ad1c0950 100644 --- a/spring-core/src/main/java/org/springframework/util/MimeTypeUtils.java +++ b/spring-core/src/main/java/org/springframework/util/MimeTypeUtils.java @@ -428,7 +428,7 @@ public abstract class MimeTypeUtils { private final Function generator; - private volatile int size = 0; + private volatile int size; public ConcurrentLruCache(int maxSize, Function generator) { Assert.isTrue(maxSize > 0, "LRU max size should be positive"); diff --git a/spring-messaging/src/main/java/org/springframework/messaging/rsocket/annotation/support/RSocketRequesterMethodArgumentResolver.java b/spring-messaging/src/main/java/org/springframework/messaging/rsocket/annotation/support/RSocketRequesterMethodArgumentResolver.java index dbba09d3c20..b5598b34c25 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/rsocket/annotation/support/RSocketRequesterMethodArgumentResolver.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/rsocket/annotation/support/RSocketRequesterMethodArgumentResolver.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2020 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -60,7 +60,7 @@ public class RSocketRequesterMethodArgumentResolver implements HandlerMethodArgu return Mono.just(requester); } else if (RSocket.class.isAssignableFrom(type)) { - return Mono.just(requester.rsocket()); + return Mono.justOrEmpty(requester.rsocket()); } else { return Mono.error(new IllegalArgumentException("Unexpected parameter type: " + parameter)); diff --git a/spring-tx/src/main/java/org/springframework/dao/support/PersistenceExceptionTranslationInterceptor.java b/spring-tx/src/main/java/org/springframework/dao/support/PersistenceExceptionTranslationInterceptor.java index 77278743326..757d1f9b591 100644 --- a/spring-tx/src/main/java/org/springframework/dao/support/PersistenceExceptionTranslationInterceptor.java +++ b/spring-tx/src/main/java/org/springframework/dao/support/PersistenceExceptionTranslationInterceptor.java @@ -146,7 +146,8 @@ public class PersistenceExceptionTranslationInterceptor else { PersistenceExceptionTranslator translator = this.persistenceExceptionTranslator; if (translator == null) { - Assert.state(this.beanFactory != null, "Cannot use PersistenceExceptionTranslator autodetection without ListableBeanFactory"); + Assert.state(this.beanFactory != null, + "Cannot use PersistenceExceptionTranslator autodetection without ListableBeanFactory"); translator = detectPersistenceExceptionTranslators(this.beanFactory); this.persistenceExceptionTranslator = translator; } @@ -157,16 +158,15 @@ public class PersistenceExceptionTranslationInterceptor /** * Detect all PersistenceExceptionTranslators in the given BeanFactory. - * @param beanFactory the ListableBeanFactory to obtaining all - * PersistenceExceptionTranslators from + * @param bf the ListableBeanFactory to obtain PersistenceExceptionTranslators from * @return a chained PersistenceExceptionTranslator, combining all - * PersistenceExceptionTranslators found in the factory + * PersistenceExceptionTranslators found in the given bean factory * @see ChainedPersistenceExceptionTranslator */ - protected PersistenceExceptionTranslator detectPersistenceExceptionTranslators(ListableBeanFactory beanFactory) { + protected PersistenceExceptionTranslator detectPersistenceExceptionTranslators(ListableBeanFactory bf) { // Find all translators, being careful not to activate FactoryBeans. Map pets = BeanFactoryUtils.beansOfTypeIncludingAncestors( - beanFactory, PersistenceExceptionTranslator.class, false, false); + bf, PersistenceExceptionTranslator.class, false, false); ChainedPersistenceExceptionTranslator cpet = new ChainedPersistenceExceptionTranslator(); for (PersistenceExceptionTranslator pet : pets.values()) { cpet.addDelegate(pet); diff --git a/spring-web/src/main/java/org/springframework/http/MediaType.java b/spring-web/src/main/java/org/springframework/http/MediaType.java index 9fd8e2ff87e..e5ee46e15e5 100644 --- a/spring-web/src/main/java/org/springframework/http/MediaType.java +++ b/spring-web/src/main/java/org/springframework/http/MediaType.java @@ -49,7 +49,6 @@ import org.springframework.util.StringUtils; * @see * HTTP 1.1: Semantics and Content, section 3.1.1.1 */ -@SuppressWarnings("deprecation") public class MediaType extends MimeType implements Serializable { private static final long serialVersionUID = 2069937152339670231L; @@ -647,7 +646,7 @@ public class MediaType extends MimeType implements Serializable { */ public static List asMediaTypes(List mimeTypes) { List mediaTypes = new ArrayList<>(mimeTypes.size()); - for(MimeType mimeType : mimeTypes) { + for (MimeType mimeType : mimeTypes) { mediaTypes.add(MediaType.asMediaType(mimeType)); } return mediaTypes; diff --git a/spring-web/src/main/java/org/springframework/web/bind/support/WebExchangeDataBinder.java b/spring-web/src/main/java/org/springframework/web/bind/support/WebExchangeDataBinder.java index 4cb29e13f04..1114de7b612 100644 --- a/spring-web/src/main/java/org/springframework/web/bind/support/WebExchangeDataBinder.java +++ b/spring-web/src/main/java/org/springframework/web/bind/support/WebExchangeDataBinder.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2020 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -64,7 +64,7 @@ public class WebExchangeDataBinder extends WebDataBinder { /** * Bind query params, form data, and or multipart form data to the binder target. - * @param exchange the current exchange. + * @param exchange the current exchange * @return a {@code Mono} when binding is complete */ public Mono bind(ServerWebExchange exchange) { diff --git a/spring-web/src/main/java/org/springframework/web/bind/support/WebRequestDataBinder.java b/spring-web/src/main/java/org/springframework/web/bind/support/WebRequestDataBinder.java index eff3cde7703..c9673eace57 100644 --- a/spring-web/src/main/java/org/springframework/web/bind/support/WebRequestDataBinder.java +++ b/spring-web/src/main/java/org/springframework/web/bind/support/WebRequestDataBinder.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2020 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -109,12 +109,12 @@ public class WebRequestDataBinder extends WebDataBinder { */ public void bind(WebRequest request) { MutablePropertyValues mpvs = new MutablePropertyValues(request.getParameterMap()); - if (isMultipartRequest(request) && request instanceof NativeWebRequest) { + if (request instanceof NativeWebRequest) { MultipartRequest multipartRequest = ((NativeWebRequest) request).getNativeRequest(MultipartRequest.class); if (multipartRequest != null) { bindMultipart(multipartRequest.getMultiFileMap(), mpvs); } - else { + else if (isMultipartRequest(request)) { HttpServletRequest servletRequest = ((NativeWebRequest) request).getNativeRequest(HttpServletRequest.class); if (servletRequest != null) { bindParts(servletRequest, mpvs); @@ -130,7 +130,7 @@ public class WebRequestDataBinder extends WebDataBinder { */ private boolean isMultipartRequest(WebRequest request) { String contentType = request.getHeader("Content-Type"); - return StringUtils.startsWithIgnoreCase(contentType, "multipart"); + return StringUtils.startsWithIgnoreCase(contentType, "multipart/"); } private void bindParts(HttpServletRequest request, MutablePropertyValues mpvs) { diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/PathVariableMethodArgumentResolver.java b/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/PathVariableMethodArgumentResolver.java index 8096a8adf9f..2d53ad24c31 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/PathVariableMethodArgumentResolver.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/PathVariableMethodArgumentResolver.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2020 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -85,7 +85,6 @@ public class PathVariableMethodArgumentResolver extends AbstractNamedValueSyncAr } @Override - @SuppressWarnings("unchecked") protected Object resolveNamedValue(String name, MethodParameter parameter, ServerWebExchange exchange) { String attributeName = HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE; return exchange.getAttributeOrDefault(attributeName, Collections.emptyMap()).get(name); @@ -97,7 +96,6 @@ public class PathVariableMethodArgumentResolver extends AbstractNamedValueSyncAr } @Override - @SuppressWarnings("unchecked") protected void handleResolvedValue( @Nullable Object arg, String name, MethodParameter parameter, Model model, ServerWebExchange exchange) { diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/HandlerExecutionChain.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/HandlerExecutionChain.java index b737f5a01ad..be267264e91 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/HandlerExecutionChain.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/HandlerExecutionChain.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2020 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -88,14 +88,23 @@ public class HandlerExecutionChain { return this.handler; } + /** + * Add the given interceptor to the end of this chain. + */ public void addInterceptor(HandlerInterceptor interceptor) { initInterceptorList().add(interceptor); } + /** + * Add the given interceptor at the specified index of this chain. + */ public void addInterceptor(int index, HandlerInterceptor interceptor) { initInterceptorList().add(index, interceptor); } + /** + * Add the given interceptors to the end of this chain. + */ public void addInterceptors(HandlerInterceptor... interceptors) { if (!ObjectUtils.isEmpty(interceptors)) { CollectionUtils.mergeArrayIntoCollection(interceptors, initInterceptorList()); @@ -192,13 +201,16 @@ public class HandlerExecutionChain { HandlerInterceptor[] interceptors = getInterceptors(); if (!ObjectUtils.isEmpty(interceptors)) { for (int i = interceptors.length - 1; i >= 0; i--) { - if (interceptors[i] instanceof AsyncHandlerInterceptor) { + HandlerInterceptor interceptor = interceptors[i]; + if (interceptor instanceof AsyncHandlerInterceptor) { try { - AsyncHandlerInterceptor asyncInterceptor = (AsyncHandlerInterceptor) interceptors[i]; + AsyncHandlerInterceptor asyncInterceptor = (AsyncHandlerInterceptor) interceptor; asyncInterceptor.afterConcurrentHandlingStarted(request, response, this.handler); } catch (Throwable ex) { - logger.error("Interceptor [" + interceptors[i] + "] failed in afterConcurrentHandlingStarted", ex); + if (logger.isErrorEnabled()) { + logger.error("Interceptor [" + interceptor + "] failed in afterConcurrentHandlingStarted", ex); + } } } } diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractHandlerMapping.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractHandlerMapping.java index beee0ce55d3..dd630ce936e 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractHandlerMapping.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractHandlerMapping.java @@ -301,22 +301,22 @@ public abstract class AbstractHandlerMapping extends WebApplicationObjectSupport } /** - * Detect beans of type {@link MappedInterceptor} and add them to the list of mapped interceptors. - *

This is called in addition to any {@link MappedInterceptor MappedInterceptors} that may have been provided - * via {@link #setInterceptors}, by default adding all beans of type {@link MappedInterceptor} - * from the current context and its ancestors. Subclasses can override and refine this policy. - * @param mappedInterceptors an empty list to add {@link MappedInterceptor} instances to + * Detect beans of type {@link MappedInterceptor} and add them to the list + * of mapped interceptors. + *

This is called in addition to any {@link MappedInterceptor}s that may + * have been provided via {@link #setInterceptors}, by default adding all + * beans of type {@link MappedInterceptor} from the current context and its + * ancestors. Subclasses can override and refine this policy. + * @param mappedInterceptors an empty list to add to */ protected void detectMappedInterceptors(List mappedInterceptors) { - mappedInterceptors.addAll( - BeanFactoryUtils.beansOfTypeIncludingAncestors( - obtainApplicationContext(), MappedInterceptor.class, true, false).values()); + mappedInterceptors.addAll(BeanFactoryUtils.beansOfTypeIncludingAncestors( + obtainApplicationContext(), MappedInterceptor.class, true, false).values()); } /** - * Initialize the specified interceptors, checking for {@link MappedInterceptor MappedInterceptors} and - * adapting {@link HandlerInterceptor}s and {@link WebRequestInterceptor HandlerInterceptor}s and - * {@link WebRequestInterceptor}s if necessary. + * Initialize the specified interceptors adapting + * {@link WebRequestInterceptor}s to {@link HandlerInterceptor}. * @see #setInterceptors * @see #adaptInterceptor */ @@ -333,13 +333,13 @@ public abstract class AbstractHandlerMapping extends WebApplicationObjectSupport } /** - * Adapt the given interceptor object to the {@link HandlerInterceptor} interface. - *

By default, the supported interceptor types are {@link HandlerInterceptor} - * and {@link WebRequestInterceptor}. Each given {@link WebRequestInterceptor} - * will be wrapped in a {@link WebRequestHandlerInterceptorAdapter}. - * Can be overridden in subclasses. - * @param interceptor the specified interceptor object - * @return the interceptor wrapped as HandlerInterceptor + * Adapt the given interceptor object to {@link HandlerInterceptor}. + *

By default, the supported interceptor types are + * {@link HandlerInterceptor} and {@link WebRequestInterceptor}. Each given + * {@link WebRequestInterceptor} is wrapped with + * {@link WebRequestHandlerInterceptorAdapter}. + * @param interceptor the interceptor + * @return the interceptor downcast or adapted to HandlerInterceptor * @see org.springframework.web.servlet.HandlerInterceptor * @see org.springframework.web.context.request.WebRequestInterceptor * @see WebRequestHandlerInterceptorAdapter @@ -358,7 +358,8 @@ public abstract class AbstractHandlerMapping extends WebApplicationObjectSupport /** * Return the adapted interceptors as {@link HandlerInterceptor} array. - * @return the array of {@link HandlerInterceptor HandlerInterceptors}, or {@code null} if none + * @return the array of {@link HandlerInterceptor HandlerInterceptor}s, + * or {@code null} if none */ @Nullable protected final HandlerInterceptor[] getAdaptedInterceptors() { @@ -367,8 +368,8 @@ public abstract class AbstractHandlerMapping extends WebApplicationObjectSupport } /** - * Return all configured {@link MappedInterceptor MappedInterceptors} as an array. - * @return the array of {@link MappedInterceptor MappedInterceptors}, or {@code null} if none + * Return all configured {@link MappedInterceptor}s as an array. + * @return the array of {@link MappedInterceptor}s, or {@code null} if none */ @Nullable protected final MappedInterceptor[] getMappedInterceptors() { @@ -447,7 +448,7 @@ public abstract class AbstractHandlerMapping extends WebApplicationObjectSupport * Build a {@link HandlerExecutionChain} for the given handler, including * applicable interceptors. *

The default implementation builds a standard {@link HandlerExecutionChain} - * with the given handler, the handler mapping's common interceptors, and any + * with the given handler, the common interceptors of the handler mapping, and any * {@link MappedInterceptor MappedInterceptors} matching to the current request URL. Interceptors * are added in the order they were registered. Subclasses may override this * in order to extend/rearrange the list of interceptors. @@ -529,12 +530,12 @@ public abstract class AbstractHandlerMapping extends WebApplicationObjectSupport if (CorsUtils.isPreFlightRequest(request)) { HandlerInterceptor[] interceptors = chain.getInterceptors(); - chain = new HandlerExecutionChain(new PreFlightHandler(config), interceptors); + return new HandlerExecutionChain(new PreFlightHandler(config), interceptors); } else { chain.addInterceptor(0, new CorsInterceptor(config)); + return chain; } - return chain; } diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/i18n/CookieLocaleResolver.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/i18n/CookieLocaleResolver.java index eb72478a24d..557bf7801e8 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/i18n/CookieLocaleResolver.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/i18n/CookieLocaleResolver.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2020 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -335,7 +335,6 @@ public class CookieLocaleResolver extends CookieGenerator implements LocaleConte * @see #setDefaultLocale * @see javax.servlet.http.HttpServletRequest#getLocale() */ - @Nullable protected Locale determineDefaultLocale(HttpServletRequest request) { Locale defaultLocale = getDefaultLocale(); if (defaultLocale == null) { From 7fdb33a105d18a452225f0b2e10accb7ad334c88 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Fri, 7 Aug 2020 13:03:28 +0200 Subject: [PATCH 4/5] Upgrade to Jetty 9.4.31, Groovy 2.5.13, Hibernate ORM 5.4.19, EclipseLink 2.7.7, Checkstyle 8.35 --- build.gradle | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/build.gradle b/build.gradle index 6bd1fd31c61..cef0af690f9 100644 --- a/build.gradle +++ b/build.gradle @@ -30,7 +30,7 @@ configure(allprojects) { project -> mavenBom "io.netty:netty-bom:4.1.51.Final" mavenBom "io.projectreactor:reactor-bom:Dysprosium-SR10" mavenBom "io.rsocket:rsocket-bom:1.0.1" - mavenBom "org.eclipse.jetty:jetty-bom:9.4.30.v20200611" + mavenBom "org.eclipse.jetty:jetty-bom:9.4.31.v20200723" mavenBom "org.jetbrains.kotlin:kotlin-bom:1.3.72" mavenBom "org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.3.5" mavenBom "org.junit:junit-bom:5.6.2" @@ -50,7 +50,7 @@ configure(allprojects) { project -> entry 'aspectjtools' entry 'aspectjweaver' } - dependencySet(group: 'org.codehaus.groovy', version: '2.5.12') { + dependencySet(group: 'org.codehaus.groovy', version: '2.5.13') { entry 'groovy' entry 'groovy-jsr223' entry 'groovy-templates' @@ -115,7 +115,7 @@ configure(allprojects) { project -> dependency "net.sf.ehcache:ehcache:2.10.6" dependency "org.ehcache:jcache:1.0.1" dependency "org.ehcache:ehcache:3.4.0" - dependency "org.hibernate:hibernate-core:5.4.18.Final" + dependency "org.hibernate:hibernate-core:5.4.19.Final" dependency "org.hibernate:hibernate-validator:6.1.5.Final" dependency "org.webjars:webjars-locator-core:0.45" dependency "org.webjars:underscorejs:1.8.3" @@ -225,7 +225,7 @@ configure(allprojects) { project -> dependency "com.ibm.websphere:uow:6.0.2.17" dependency "com.jamonapi:jamon:2.82" dependency "joda-time:joda-time:2.10.6" - dependency "org.eclipse.persistence:org.eclipse.persistence.jpa:2.7.6" + dependency "org.eclipse.persistence:org.eclipse.persistence.jpa:2.7.7" dependency "org.javamoney:moneta:1.3" dependency "com.sun.activation:javax.activation:1.2.0" @@ -325,7 +325,7 @@ configure([rootProject] + javaProjects) { project -> } checkstyle { - toolVersion = "8.34" + toolVersion = "8.35" configDir = rootProject.file("src/checkstyle") } From 692c5f292da714c251280058d58e8c05176ef478 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Fri, 7 Aug 2020 13:11:48 +0200 Subject: [PATCH 5/5] Polishing --- .../beans/factory/support/DefaultListableBeanFactory.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java index d2121b23b97..52c5f67aef9 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java @@ -325,9 +325,9 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto this.allowBeanDefinitionOverriding = otherListableFactory.allowBeanDefinitionOverriding; this.allowEagerClassLoading = otherListableFactory.allowEagerClassLoading; this.dependencyComparator = otherListableFactory.dependencyComparator; - // A clone of the AutowireCandidateResolver since it is potentially BeanFactoryAware... + // A clone of the AutowireCandidateResolver since it is potentially BeanFactoryAware setAutowireCandidateResolver(otherListableFactory.getAutowireCandidateResolver().cloneIfNecessary()); - // Make resolvable dependencies (e.g. ResourceLoader) available here as well... + // Make resolvable dependencies (e.g. ResourceLoader) available here as well this.resolvableDependencies.putAll(otherListableFactory.resolvableDependencies); } } @@ -354,7 +354,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto } @Override - public ObjectProvider getBeanProvider(Class requiredType) { + public ObjectProvider getBeanProvider(Class requiredType) { Assert.notNull(requiredType, "Required type must not be null"); return getBeanProvider(ResolvableType.forRawClass(requiredType)); } @@ -530,7 +530,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto matchFound = isTypeMatch(beanName, type, allowFactoryBeanInit); } } - else { + else { if (includeNonSingletons || isNonLazyDecorated || (allowFactoryBeanInit && isSingleton(beanName, mbd, dbd))) { matchFound = isTypeMatch(beanName, type, allowFactoryBeanInit);