- ScriptedSubscriber has been renamed to Verifier
- The Publisher is passed to create() instead of verify()
- No more need to specify the generic type explicitly
- Version is now sync with reactor-core
Issue: SPR-14800
Reactor recently added the `ScriptedSubscriber` in its new
`reactor-addons` module. This `Subscriber` revissits the previous
`TestSubscriber` with many improvements, including:
* scripting each expectation
* builder API that guides you until the final verification step
* virtual time support
This commit refactor all existing tests to use this new
infrastructure and removed the `TestSubscriber` implementation.
Issue: SPR-14800
This commit removes the usage of Reactor adapters (about to
be moved from Reactor Core to a new Reactor Adapter module).
Instead, RxReactiveStreams is now used for adapting RxJava
1 and Flowable methods are used for RxJava 2.
Issue: SPR-14824
This commit adds the necessary infrastructure for the support of HTTP
Range requests. The new `ResourceRegionEncoder` can write
`ResourceRegion` objects as streams of bytes.
The `ResourceRegionEncoder` relies on an encoding hint
`BOUNDARY_STRING_HINT`. If present, the encoder infers that multiple
`ResourceRegion`s should be encoded and that the provided boundary
String should be used to separate ranges by mime boundaries.
If that hint is absent, only a single resource region is encoded.
Issue: SPR-14664
Added readableChannel() to Resource, which returns a
java.nio.ReadableByteChannel. The default implementation uses
Channels.newChannel() to create a channel based on what is returned from
getInputStream(). Subclasses have more effecient, file-based
implementations.
Issue: SPR-14698
Fixed bug where the returned Flux from DataBufferUtils.read() would be
completed prematurely if the channel was not ready to read, but did
not reach the end of the file either.
This commit documents the regexp support in `AntPathMatcher` when
matching for URL patterns. This support is also mentioned in places
where developers can register patterns for ViewControllers or resource
handlers.
Issue: SPR-14652
This commit adds a "spring-context-indexer" module that can be added to
any project in order to generate an index of candidate components defined
in the project.
`CandidateComponentsIndexer` is a standard annotation processor that
looks for source files with target annotations (typically `@Component`)
and references them in a `META-INF/spring.components` generated file.
Each entry in the index is the fully qualified name of a candidate
component and the comma-separated list of stereotypes that apply to that
candidate. A typical example of a stereotype is `@Component`. If a
project has a `com.example.FooService` annotated with `@Component` the
following `META-INF/spring.components` file is generated at compile time:
```
com.example.FooService=org.springframework.stereotype.Component
```
A new `@Indexed` annotation can be added on any annotation to instructs
the scanner to include a source file that contains that annotation. For
instance, `@Component` is meta-annotated with `@Indexed` now and adding
`@Indexed` to more annotation types will transparently improve the index
with additional information. This also works for interaces or parent
classes: adding `@Indexed` on a `Repository` base interface means that
the indexed can be queried for its implementation by using the fully
qualified name of the `Repository` interface.
The indexer also adds any class or interface that has a type-level
annotation from the `javax` package. This includes obviously JPA
(`@Entity` and related) but also CDI (`@Named`, `@ManagedBean`) and
servlet annotations (i.e. `@WebFilter`). These are meant to handle
cases where a component needs to identify candidates and use classpath
scanning currently.
If a `package-info.java` file exists, the package is registered using
a "package-info" stereotype.
Such files can later be reused by the `ApplicationContext` to avoid
using component scan. A global `CandidateComponentsIndex` can be easily
loaded from the current classpath using `CandidateComponentsIndexLoader`.
The core framework uses such infrastructure in two areas: to retrieve
the candidate `@Component`s and to build a default `PersistenceUnitInfo`.
Rather than scanning the classpath and using ASM to identify candidates,
the index is used if present.
As long as the include filters refer to an annotation that is directly
annotated with `@Indexed` or an assignable type that is directly
annotated with `@Indexed`, the index can be used since a dedicated entry
wil be present for that type. If any other unsupported include filter is
specified, we fallback on classpath scanning.
In case the index is incomplete or cannot be used, The
`spring.index.ignore` system property can be set to `true` or,
alternatively, in a "spring.properties" at the root of the classpath.
Issue: SPR-11890
This commit adds support for HTTP header field parameters encoding, as
described in RFC5987.
Note that the default implementation still relies on US-ASCII encoding,
as the latest rfc7230 Section 3.2.4 says that:
> Newly defined header fields SHOULD limit their field values to
US-ASCII octets
Issue: SPR-14547
reactor.test.TestSubscriber will not be part of Reactor Core
3.0.0 since it needs to be refactored to fit all the needs
expressed by the users. It is likely to be back later in one
of the Reactor Core 3.0.x releases.
This commit anticipate this removal by temporarily copying
TestSubscriber in spring-core test classes. As soon as
the new TestSubscriber will be available in Reactor Core,
Spring Framework reactive tests will use it again.
DataSourceUtils moved to main core.io.buffer package.
Consistently named Jackson2JsonDecoder/Encoder and Jaxb2XmlDecoder/Encoder.
Plenty of related polishing.
xmlunit 2.1.0 is the latest release for xmlunit.
Most of the xmlunit functionality used within spring-framework
was done through the xmlunit 1.x helper class
`org.custommonkey.xmlunit.XMLAssert`.
As of xmlunit 2.0.0 most of the XML comparison methods are done
through hamcrest matchers exposed by the xmlunit-matchers
library. In some cases during the migration, the matchers
had to be customized with custom `NodeMatcher` or
`DifferenceEvaluator` instances in order to keep the assertions
correct (they were performed with xmlunit 1.x previously).
Issue: SPR-14043
This commit changes the reactive flushing mechanism to use a newly
introduced writeAndFlushWith(Publisher<Publisher<DataBuffer>>) on
ReactiveHttpOutputMessage instead of using the FlushingDataBuffer.
Issue: https://github.com/spring-projects/spring-reactive/issues/125
This commit makes use of the new Supplier<String> variants of utility
methods in org.springframework.util.Assert within the spring-core
module.
Issue: SPR-14450
Prior to this commit, utility methods in
org.springframework.util.Assert accepted String arguments for custom
error messages. Such Strings are evaluated (e.g., concatenated)
eagerly, and for performance reasons, it was therefore not always
possible to make use of these utility methods. Consequently, there are
several places in the code base that "inline" identical functionality
in order to lazily evaluate error message concatenation and avoid an
unnecessary performance penalty. This leads to verbose code like the
following.
if (!contextPath.startsWith("/")) {
throw new IllegalArgumentException("contextPath '" + contextPath +
"' must start with '/'.");
}
if (contextPath.endsWith("/")) {
throw new IllegalArgumentException("contextPath '" + contextPath +
"' must not end with '/'.");
}
This commit addresses this shortcoming by introducing Supplier<String>
variants of all utility methods in org.springframework.util.Assert that
allow custom error messages to be evaluated lazily via a lambda
expression that is only evaluated if the assertion fails. This results
in a simplification of the previous examples as follows.
Assert.isTrue(contextPath.startsWith("/"), () -> "contextPath '" +
contextPath + "' must start with '/'.");
Assert.isTrue(!contextPath.endsWith("/"), () -> "contextPath '" +
contextPath + "' must not end with '/'.");
Issue: SPR-14450
This commit adds a test runtime dependency on log4j 2 for every project
and migrates all log4j.properties files to log4j2-test.xml files.
Issue: SPR-14431
This commit also removes the corresponding deprecated Servlet MVC variant and updates DispatcherServlet.properties to point to RequestMappingHandlerMapping/Adapter by default.
Issue: SPR-14129
Prior to this commit, the latest optimizations introduced in SPR-13913
would prevent matching when patterns contained spaces. Indeed, the
optimized path would not fully tokenize the paths nor trim the tokens,
as the "longer" code path does.
This commit disables this optimized path when the `trimTokens` option is
set to `true`.
Also, the `trimTokens` setting is now set to `false` by default.
Issue: SPR-14247
Prior to this commit, the `ResourceHttpMessageConverter` would support
all HTTP Range requests and `MethodProcessors` would "wrap" controller
handler return values with a `HttpRangeResource` to support that use
case in Controllers.
This commit refactors that support in several ways:
* a new ResourceRegion class has been introduced
* a new, separate, ResourceRegionHttpMessageConverter handles the HTTP
range use cases when serving static resources with the
ResourceHttpRequestHandler
* the support of HTTP range requests on Controller handlers has been
removed until a better solution is found
Issue: SPR-14221, SPR-13834
Prior to this commit, the new match algorithm wouldn't work for multiple
consecutive path separators.
This commit separately matches path segments and path separators and
allows for multiple, consecutive path separators.
Issue: SPR-14141
Prior to this commit, the size of the ApplicationContext cache in the
Spring TestContext Framework could grow without bound, leading to
issues with memory and performance in large test suites.
This commit addresses this issue by introducing support for setting the
maximum cache size via a JVM system property or Spring property called
"spring.test.context.cache.maxSize". If no such property is set, a
default value of 32 will be used.
Furthermore, the DefaultContextCache has been refactored to use a
synchronized LRU cache internally instead of a ConcurrentHashMap. The
LRU cache is a simple bounded cache with a "least recently used" (LRU)
eviction policy.
Issue: SPR-8055
This commit documents the @Ignore'd test to explain that Spring does not
support a hybrid approach for annotation attribute overrides with
transitive implicit aliases.
Issue: SPR-13554
Prior to this commit, HTTP clients relying on the JDK HTTP client would
not properly reuse existing TCP connections (i.e. HTTP 1.1 persisten
connection). The SimpleClientHttpResponse would close the actual connection once the
response is handled.
As explained in the JDK documentation
(http://docs.oracle.com/javase/8/docs/technotes/guides/net/http-keepalive.html)
HTTP clients should do the following to allow resource reuse:
* consume the whole HTTP response content
* close the response inputstream once done
This commit makes sure that the response content is
totally drained and then the stream closed (and not the connection).
Issue: SPR-14040
This commit introduces a boolean alwaysProcesses() method in the
Processor API which allows for simplification across all search
algorithms within AnnotatedElementUtils.
Specifically, it is no longer necessary for process() methods to verify
that the supplied annotation is actually the sought target annotation.
In addition, duplicated code has been extracted into common methods
(e.g., hasMetaAnnotationTypes()) and common Processor implementations
(e.g., AlwaysTrueBooleanAnnotationProcessor).
This commit picks up where 2535469099 left off with added support for
"get" search semantics for merged repeatable annotations.
Specifically, this commit introduces a new
getMergedRepeatableAnnotations() method in AnnotatedElementUtils.
Issue: SPR-13973
This commit picks up where a5139f3c66 left off with added support for
"get" search semantics for multiple merged annotations.
Specifically, this commit introduces a new getAllMergedAnnotations()
method in AnnotatedElementUtils.
Issue: SPR-13486
Prior to this commit, AnnotationUtils supported searching for
repeatable annotations even if the repeatable annotation was declared
on a custom stereotype annotation. However, there was no support for
merging of attributes in composed repeatable annotations. In other
words, it was not possible for a custom annotation to override
attributes in a repeatable annotation.
This commit addresses this by introducing
findMergedRepeatableAnnotations() methods in AnnotatedElementUtils.
These new methods provide full support for explicit annotation
attribute overrides configured via @AliasFor (as well as
convention-based overrides) with "find semantics".
Issue: SPR-13973
Prior to this commit it was possible to search for the 1st merged
annotation above an annotated element. It was also possible to search
for annotation attributes aggregated from all annotations above an
annotated element; however, it was impossible to search for all
composed annotations above an annotated element and have the results as
synthesized merged annotations instead of a multi-map of attributes.
This commit introduces a new findAllMergedAnnotations() method in
AnnotatedElementUtils that finds all annotations of the specified type
within the annotation hierarchy above the supplied element. For each
such annotation found, it merges that annotation's attributes with
matching attributes from annotations in lower levels of the annotation
hierarchy and synthesizes the results back into an annotation of the
specified type. All such merged annotations are collected and returned
as a set.
Issue: SPR-13486
This commit introduces tests that verify the status quo for finding
multiple merged composed annotations on a single annotated element.
Issue: SPR-13486
Prior to this commit, it was possible that implicit aliases and
transitive implicit aliases (configured via @AliasFor) might not be
honored in certain circumstances, in particular if implicit aliases
were declared to override different attributes within an alias pair in
the target meta-annotation.
This commit addresses this issue by ensuring that all aliased
attributes in the target meta-annotation are overridden during the
merge process in AnnotatedElementUtils.
In addition, concrete default values for attributes in a
meta-annotation declaration can now be effectively shadowed by
transitive implicit aliases in composed annotations.
Issue: SPR-14069
This commit primarily allows for a `SynthesizingMethodParameter` to be
created for a `Constructor` parameter but also introduces an additional
overloaded constructor from `MethodParameter`.
Issue: SPR-14054
This commit picks up where 8ff9e818a5
left off.
Specifically, this commit introduces support that allows a single
element attribute to override an array attribute with a matching
component type when synthesizing annotations (e.g., in annotations
synthesized from attributes that have been merged from the annotation
hierarchy above a composed annotation).
Issue: SPR-13972
Before this commit, specifying the charset to use with produces or
consumes @RequestMapping attributes resulted in default charset
loss. That was really annoying for JSON for example, where using
UTF-8 charset is mandatory in a lot of use cases.
This commit adds a defaultCharset property to
AbstractHttpMessageConverter in order to avoid losing the
default charset when specifying the charset with these
@RequestMapping attributes.
It changes slightly the default behavior (that's why we have waited
4.3), but it is much more error prone, and will match with most
user's expectations since the charset loss was accidental in most
use cases (users usually just want to limit the media type supported
by a specific handler method).
Issue: SPR-13631
Refine the optimizations made in 6f55ab69 in order to restore binary
compatibility and resolve a regression.
Tests of the form pathMatcher.match("/foo/bar/**", "/foo/bar") should
return true as this was the behavior in Spring 4.2.
Issue: SPR-13913
This commit speeds up the AntPathMatcher implementation by
pre-processing patterns and checking that candidates are likely
matches if they start with the static prefix of the pattern.
Those changes can result in a small performance penalty for positive
matches, but with a significant boost for checking candidates that don't
match. Overall, this tradeoff is acceptable since this feature is often
used to select a few matching patterns in a much bigger list.
This will lead to small but consistent performance improvements in
Spring MVC when matching a given request with the available routes.
Issue: SPR-13913
This change updates all cases where callbacks are invoked to catch and
suppress errors (since there is not match to do with and error from
a callback be it success or failure).
Also updated is the contract itself to clarify this and emphasize the
callbacks are really notifications for the outcome of the
ListenableFuture not the callbacks themselves.
Issue: SPR-13785
JIRA: https://jira.spring.io/browse/SPR-13784
JDK8 and Apache Commons Codec support the RFC 4648
"URL and Filename Safe" Base64 alphabet.
Add methods to `Base64Utils` to support this feature.
This commit reworks the arrangement to a centralized cache, avoiding any extra reflection attempts if a cache entry is known already. In the course of this, it also enforces toXXX methods to be declared as non-static now (which is the only sensible arrangement anyway).
Issue: SPR-13703
The goal is to avoid String name comparisons in favor of annotation type identity checks wherever possible. Also, we avoid double getDeclaredAnnotations/getAnnotations checks on anything other than Classes now, since we'd just get the same result in a fresh array.
Issue: SPR-13621
Improve the performance of the `getMergedAnnotationAttributes` and
`isAnnotated` methods in `AnnotatedElementUtils` by returning
immediately when the element had no annotations.
Issue: SPR-13621
Previously, the only way to add the collection converters to a registry
was to add *all* default converters. A new "addCollectionConverters"
public method is now available to only register them.
Issue: SPR-13618
This commit migrates all remaining tests from JUnit 3 to JUnit 4, with
the exception of Spring's legacy JUnit 3.8 based testing framework that
is still in use in the spring-orm module.
Issue: SPR-13514
This commit picks up where 3eacb837c2
(SPR-13345) left off by adding support for transitive implicit aliases
configured via @AliasFor.
Issue: SPR-13405
Spring Framework 4.2 introduced support for aliases between annotation
attributes that fall into the following two categories.
1) Alias pairs: two attributes in the same annotation that use
@AliasFor to declare that they are explicit aliases for each other.
2) Meta-annotation attribute overrides: an attribute in one annotation
uses @AliasFor to declare that it is an explicit override of an
attribute in a meta-annotation.
However, the existing functionality fails to support the case where two
attributes in the same annotation both use @AliasFor to declare that
they are both explicit overrides of the same attribute in the same
meta-annotation. In such scenarios, one would intuitively assume that
two such attributes would be treated as "implicit" aliases for each
other, analogous to the existing support for explicit alias pairs.
Furthermore, an annotation may potentially declare multiple aliases
that are effectively a set of implicit aliases for each other.
This commit introduces support for implicit aliases configured via
@AliasFor through an extensive overhaul of the support for alias
lookups, validation, etc. Specifically, this commit includes the
following.
- Introduced isAnnotationMetaPresent() in AnnotationUtils.
- Introduced private AliasDescriptor class in AnnotationUtils in order
to encapsulate the parsing, validation, and comparison of both
explicit and implicit aliases configured via @AliasFor.
- Switched from single values for alias names to lists of alias names.
- Renamed getAliasedAttributeName() to getAliasedAttributeNames() in
AnnotationUtils.
- Converted alias map to contain lists of aliases in AnnotationUtils.
- Refactored the following to support multiple implicit aliases:
getRequiredAttributeWithAlias() in AnnotationAttributes,
AbstractAliasAwareAnnotationAttributeExtractor,
MapAnnotationAttributeExtractor, MergedAnnotationAttributesProcessor
in AnnotatedElementUtils, and postProcessAnnotationAttributes() in
AnnotationUtils.
- Introduced numerous tests for implicit alias support, including
AbstractAliasAwareAnnotationAttributeExtractorTestCase,
DefaultAnnotationAttributeExtractorTests, and
MapAnnotationAttributeExtractorTests.
- Updated Javadoc in @AliasFor regarding implicit aliases and in
AnnotationUtils regarding "meta-present".
Issue: SPR-13345
SocketUtils is used to find available ports on localhost; however,
prior to this commit, SocketUtils incorrectly reported a port as
available on localhost if another process was already bound to
localhost on the given port but not to other network interfaces. In
other words, SocketUtils determined that a given port was available for
some interface though not necessarily for the loopback interface.
This commit addresses this issue by refactoring SocketUtils so that it
tests the loopback interface to ensure that the port is actually
available for localhost.
Issue: SPR-13321
This commit introduces an additional test case to ensure that explicit
local attribute aliases (configured via @AliasFor) do not accidentally
override attributes of the same names in meta-annotations (i.e., by
convention).
Issue: SPR-13325
Prior to this commit, attempting to synthesize an annotation from a map
of annotation attributes that contained nested maps instead of nested
annotations would result in an exception.
This commit addresses this issue by properly synthesizing nested maps
and nested arrays of maps into nested annotations and nested arrays of
annotations, respectively.
Issue: SPR-13338
It is a configuration error if an alias is declared via @AliasFor for
an attribute in a meta-annotation and the meta-annotation is not
meta-present. However, prior to this commit, the support for validating
the configuration of @AliasFor in AnnotationUtils currently silently
ignored such errors.
This commit fixes this by throwing an AnnotationConfigurationException
whenever a required meta-annotation is not present or meta-present on
an annotation that declares an explicit alias for an attribute in the
meta-annotation.
Issue: SPR-13335
This commit aims to improve the space and time performance of
NumberUtils by invoking valueOf() factory methods instead of the
corresponding constructors when converting a number to a target class.
Prior to this commit, an explicit override for an attribute in a
meta-annotation configured via @AliasFor could potentially result in an
incorrect override of an attribute of the same name but in the wrong
meta-annotation.
This commit fixes the algorithm in getAliasedAttributeName(Method,
Class) in AnnotationUtils by ensuring that an explicit attribute
override is only applied to the configured target meta-annotation
(i.e., configured via the 'annotation' attribute in @AliasFor).
Issue: SPR-13325
SPR-11512 introduced support for annotation attribute aliases via
@AliasFor, requiring the explicit declaration of the 'attribute'
attribute. However, for aliases within an annotation, this explicit
declaration is unnecessary.
This commit improves the readability of alias pairs declared within an
annotation by introducing a 'value' attribute in @AliasFor that is an
alias for the existing 'attribute' attribute. This allows annotations
such as @ContextConfiguration from the spring-test module to declare
aliases as follows.
public @interface ContextConfiguration {
@AliasFor("locations")
String[] value() default {};
@AliasFor("value")
String[] locations() default {};
// ...
}
Issue: SPR-13289
This split avoids a package tangle (between core and core.annotation) and also allows for selective use of raw annotation exposure versus synthesized annotations, with the latter primarily applicable to web and message handler processing at this point.
Issue: SPR-13153
Prior to this commit, Spring's MimeType checked for equality between
two MIME types based on the equality of their properties maps; however,
the properties maps contain string representations of the "charset"
values. Thus, "UTF-8" is never equal to "utf-8" which breaks the
contract for character set names which must be compared in a
case-insensitive manner.
This commit addresses this issue by ensuring that "charset" properties
in MimeType instances are compared as Java Charset instances, thereby
ignoring case when checking for equality between charset names.
Issue: SPR-13157
This commit introduces a convenience method in AnnotationUtils for
synthesizing an annotation from its default attribute values.
TransactionalTestExecutionListener has been refactored to invoke this
new convenience method.
Issue: SPR-13087
This commit introduces support for automatically resolving a container
annotation configured via @Repeatable in AnnotationUtils'
getRepeatableAnnotations() and getDeclaredRepeatableAnnotations()
methods.
Issue: SPR-13068
This commit introduces a minor bug fix for getRepeatableAnnotations()
so that it fully complies with the contract of Java's
getAnnotationsByType() method with regard to repeatable annotations
declared on multiple superclasses.
Issue: SPR-13068