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
Prior to this commit, the implementation of getRepeatableAnnotation()
in Spring's AnnotationUtils complied neither with the contract of
getAnnotationsByType() nor with the contract of
getDeclaredAnnotationsByType() as defined in AnnotatedElement in Java 8.
Specifically, unexpected results can be encountered when using Spring's
support for @Repeatable annotations: either annotations show up in the
returned set in the wrong order, or annotations are returned in the set
that should not even be found based on the semantics of @Repeatable.
This commit remedies this problem by deprecating the existing
getRepeatableAnnotation() methods and replacing them with new
getRepeatableAnnotations() and getDeclaredRepeatableAnnotations()
methods that comply with the contracts of Java's getAnnotationsByType()
and getDeclaredAnnotationsByType(), respectively.
Issue: SPR-13068
The initial support for synthesizing an annotation from a Map (or
AnnotationAttributes) introduced in SPR-13067 required that the map
contain key-value pairs for every attribute defined by the supplied
annotationType. However, there are use cases that would benefit from
being able to supply a reduced set of attributes and still have the
annotation synthesized properly.
This commit refines the validation mechanism in
MapAnnotationAttributeExtractor so that a reduced set of attributes may
be supplied. Specifically, if an attribute is missing in the supplied
map the attribute will be set either to value of its alias (if an alias
value configured via @AliasFor exists) or to the value of the
attribute's default value (if defined), and otherwise an exception will
be thrown.
Furthermore, TransactionalTestExecutionListener has been refactored to
take advantage of this new feature by synthesizing an instance of
@TransactionConfiguration solely from the default values of its
declared attributes.
Issue: SPR-13087
In AnnotatedElementUtils, all methods pertaining to merging annotation
attributes have been renamed to "getMerged*()" and "findMerged*()"
accordingly. Existing methods such as getAnnotationAttributes(..) have
been deprecated in favor of the more descriptive "merged" variants.
This aligns the naming conventions in AnnotatedElementUtils with those
already present in AnnotationReadingVisitorUtils.
The use of "annotationType" as a variable name for the fully qualified
class name of an annotation type has been replaced with
"annotationName" in order to improve the readability and intent of the
code base.
In MetaAnnotationUtils.AnnotationDescriptor, getMergedAnnotation() has
been renamed to synthesizeAnnotation(), and the method is now
overridden in UntypedAnnotationDescriptor to always throw an
UnsupportedOperationException in order to avoid potential run-time
ClassCastExceptions.
Issue: SPR-11511
Prior to this commit, there existed several isEmpty() methods scattered
across various utilities such as ObjectUtils, CollectionUtils, and
StringUtils; however, each of these methods requires a cast to the type
supported for that particular variant.
This commit introduces a general-purpose isEmpty(Object) method in
ObjectUtils that transparently supports multiple object types in a
central location without the need for casts or juggling multiple
utility classes.
Issue: SPR-13119
Provide a mean to detect the actual ResolvableType based on a instance as
a counter measure to type erasure.
Upgrade the event infrastructure to detect if the event (or the payload)
implements such interface. When this is the case, the return value of
`getResolvableType` is used to validate its generic type against the
method signature of the listener.
Issue: SPR-13069
This commit introduces a "synthesized annotation" alternative to
getAnnotationAttributes() in AnnotatedElementUtils, analogous to the
recently introduced findAnnotation() methods.
Issue: SPR-13082
Spring Framework 4.2 RC1 introduced support for synthesizing an
annotation from an existing annotation in order to provide additional
functionality above and beyond that provided by Java. Specifically,
such synthesized annotations provide support for @AliasFor semantics.
As luck would have it, the same principle can be used to synthesize an
annotation from any map of attributes, and in particular, from an
instance of AnnotationAttributes.
The following highlight the major changes in this commit toward
achieving this goal.
- Introduced AnnotationAttributeExtractor abstraction and refactored
SynthesizedAnnotationInvocationHandler to delegate to an
AnnotationAttributeExtractor.
- Extracted code from SynthesizedAnnotationInvocationHandler into new
AbstractAliasAwareAnnotationAttributeExtractor and
DefaultAnnotationAttributeExtractor implementation classes.
- Introduced MapAnnotationAttributeExtractor for synthesizing an
annotation that is backed by a map or AnnotationAttributes instance.
- Introduced a variant of synthesizeAnnotation() in AnnotationUtils
that accepts a map.
- Introduced findAnnotation(*) methods in AnnotatedElementUtils that
synthesize merged AnnotationAttributes back into an annotation of the
target type.
The following classes have been refactored to use the new support for
synthesizing AnnotationAttributes back into an annotation.
- ApplicationListenerMethodAdapter
- TestAnnotationUtils
- AbstractTestContextBootstrapper
- ActiveProfilesUtils
- ContextLoaderUtils
- DefaultActiveProfilesResolver
- DirtiesContextTestExecutionListener
- TestPropertySourceAttributes
- TestPropertySourceUtils
- TransactionalTestExecutionListener
- MetaAnnotationUtils
- MvcUriComponentsBuilder
- RequestMappingHandlerMapping
In addition, this commit also includes changes to ensure that arrays
returned by synthesized annotations are properly cloned first.
Issue: SPR-13067
Prior to this commit, when a nested array of annotations was
synthesized while adapting values within an AnnotationAttributes map,
the array was improperly replaced with an array of type Annotation[]
instead of an array of the concrete annotation type, which can lead to
unexpected run-time exceptions.
This commit fixes this bug by replacing annotations in the existing
array with synthesized versions of those annotations, thereby retaining
the original array's component type.
Issue: SPR-13077
This commit introduces support in AnnotationAttributes for retrieving
nested annotations that is on par with the existing type-safe support
for retrieving nested AnnotationAttributes.
Issue: SPR-13074
AnnotationAttributes has existed for several years, but none of the
"get" methods that make up its public API are documented. In many
cases, the behavior can be inferred from the name of the method, but
for some methods there are "hidden gems" and unexpected behavior
lurking behind the scenes.
This commit addresses this issue by documenting all public methods. In
addition, the hidden support for converting single elements into
single-element arrays has also been documented and tested.
Issue: SPR-13072
This commit introduces a test that will fail if SynthesizedAnnotation is
not public as is required by the contract for getProxyClass() in
java.lang.reflect.Proxy.
Issue: SPR-13057
Enable public visibility on SynthetizedAnnotation to allow annotation
outside its package to be proxied properly. This commit is pending a
unit test that actually reproduces the problem.
Issue: SPR-13057
This commit introduces first-class support for aliases for annotation
attributes. Specifically, this commit introduces a new @AliasFor
annotation that can be used to declare a pair of aliased attributes
within a single annotation or an alias from an attribute in a custom
composed annotation to an attribute in a meta-annotation.
To support @AliasFor within annotation instances, AnnotationUtils has
been overhauled to "synthesize" any annotations returned by "get" and
"find" searches. A SynthesizedAnnotation is an annotation that is
wrapped in a JDK dynamic proxy which provides run-time support for
@AliasFor semantics. SynthesizedAnnotationInvocationHandler is the
actual handler behind the proxy.
In addition, the contract for @AliasFor is fully validated, and an
AnnotationConfigurationException is thrown in case invalid
configuration is detected.
For example, @ContextConfiguration from the spring-test module is now
declared as follows:
public @interface ContextConfiguration {
@AliasFor(attribute = "locations")
String[] value() default {};
@AliasFor(attribute = "value")
String[] locations() default {};
// ...
}
The following annotations and their related support classes have been
modified to use @AliasFor.
- @ManagedResource
- @ContextConfiguration
- @ActiveProfiles
- @TestExecutionListeners
- @TestPropertySource
- @Sql
- @ControllerAdvice
- @RequestMapping
Similarly, support for AnnotationAttributes has been reworked to
support @AliasFor as well. This allows for fine-grained control over
exactly which attributes are overridden within an annotation hierarchy.
In fact, it is now possible to declare an alias for the 'value'
attribute of a meta-annotation.
For example, given the revised declaration of @ContextConfiguration
above, one can now develop a composed annotation with a custom
attribute override as follows.
@ContextConfiguration
public @interface MyTestConfig {
@AliasFor(
annotation = ContextConfiguration.class,
attribute = "locations"
)
String[] xmlFiles();
// ...
}
Consequently, the following are functionally equivalent.
- @MyTestConfig(xmlFiles = "test.xml")
- @ContextConfiguration("test.xml")
- @ContextConfiguration(locations = "test.xml").
Issue: SPR-11512, SPR-11513
Prior to this commit, the documentation in AnnotationUtils was
inconsistent, and at times even misleading, with regard to finding
annotations that are "present" or "directly present" on annotated
elements.
This commit defines the terminology used within AnnotationUtils and
introduces the explicit notion of "meta-present" to denote that
annotations are present within annotation hierarchies above annotated
elements.
Issue: SPR-13030
This commit updates the "get semantics" search algorithm used in
`AnnotatedElementUtils` so that locally declared 'composed annotations'
are favored over inherited annotations.
Specifically, the internal `searchWithGetSemantics()` method now
searches locally declared annotations before searching inherited
annotations.
All TODOs in `AnnotatedElementUtilsTests` have been completed, and all
ignored tests have been reinstated.
Issue: SPR-11598
This commit improves the documentation for AnnotationUtils and
AnnotatedElementUtils by explaining that the scope of most annotation
searches is limited to finding the first such annotation, resulting in
additional such annotations being silently ignored.
Issue: SPR-13015
In general, the Spring Framework aims to construct error message
strings only if an actual error has occurred. This seems to be the
common pattern in the codebase and saves both CPU and memory. However,
there are some places where eager error message formatting occurs
unnecessarily.
This commit addresses this issue in the following classes:
AdviceModeImportSelector, AnnotationAttributes, and
ReadOnlySystemAttributesMap.
The change in ReadOnlySystemAttributesMap also avoids a potential
NullPointerException.
Issue: SPR-13007
Prior to this commit, the `getAnnotation()` method in `TypeDescriptor`
only supported a single level of meta-annotations. In other words, the
annotation hierarchy would not be exhaustively searched.
This commit provides support for arbitrary levels of meta-annotations
in `TypeDescriptor` by delegating to `AnnotationUtils.findAnnotation()`
within `TypeDescriptor.getAnnotation()`.
Issue: SPR-12793
Prior to this commit, AntPathMatcher would not correctly combine a path
that ends with a separator with a path that starts with a separator.
For example, `/foo/` + `/bar` combined into `/foo//bar`.
Specifically, this commit:
- Removes the duplicated separator in combined paths
- Improves RequestMappingInfo's toString() representation
- Fixes Javadoc formatting in AntPathMatcher
- Polishes AntPathMatcherTests
- Polishes Javadoc in AbstractRequestCondition
Issue: SPR-12975
This commit picks up where SPR-11483 left off, with the goal of
eliminating all unnecessary inspection of core JDK annotations in
Spring's annotation search algorithms in AnnotatedElementUtils and
AnnotationMetadataReadingVisitor.
Issue: SPR-12989
- Methods which search for a specific annotation now properly ensure
that the sought annotation was actually found.
- Both the "get" and the "find" search algorithms no longer needlessly
traverse meta-annotation hierarchies twice.
- Both the "get" and the "find" search algorithms now properly
increment the metaDepth when recursively searching within the
meta-annotation hierarchy.
- Redesigned getMetaAnnotationTypes() so that it doesn't needlessly
search irrelevant annotations.
- Documented and tested hasMetaAnnotationTypes().
- Documented isAnnotated().
Issue: SPR-11514
This commit documents the status quo for the getMetaAnnotationTypes()
method in AnnotatedElementUtils and adds appropriate regression tests to
AnnotatedElementUtilsTests.
In addition, this commit also introduces a SimpleAnnotationProcessor
base class in AnnotatedElementUtils.
Issue: SPR-11514
This commit consistently documents the 'element' and 'annotationType'
method arguments throughout AnnotatedElementUtils.
In addition, this commit introduces assertions against preconditions
for all 'element' and 'annotationType' method arguments.
Issue: SPR-11514
This commit introduces support for finding annotations on abstract,
bridge, and interface methods in AnnotatedElementUtils.
- Introduced dedicated findAnnotationAttributes() methods in
AnnotatedElementUtils that provide first-class support for
processing methods, class hierarchies, interfaces, bridge methods,
etc.
- Introduced find/get search algorithm dichotomy in
AnnotatedElementUtils which is visible in the public API as well as
in the internal implementation. This was necessary in order to
maintain backwards compatibility with the existing API (even though
it was undocumented).
- Reverted all recent changes made to the "get semantics" search
algorithm in AnnotatedElementUtils in order to ensure backwards
compatibility, and reverted recent changes to
JtaTransactionAnnotationParser and SpringTransactionAnnotationParser
accordingly.
- Documented internal AnnotatedElementUtils.Processor<T> interface.
- Enabled failing tests and introduced
findAnnotationAttributesFromBridgeMethod() test in
AnnotatedElementUtilsTests.
- Refactored ApplicationListenerMethodAdapter.getCondition() and
enabled failing test in TransactionalEventListenerTests.
- AnnotationUtils.isInterfaceWithAnnotatedMethods() is now package
private.
Issue: SPR-12738, SPR-11514, SPR-11598
This commit introduces support in AnnotatedElementUtils for finding
annotations declared on interfaces at the type level.
NB: this commit does not include support for finding annotations
declared on interface methods.
In order to maintain backward compatibility with @Transactional
annotation attribute processing, a new getAnnotationAttributes() method
has been added to AnnotatedElementUtils that provides a flag to control
whether interfaces should be searched.
SpringTransactionAnnotationParser and JtaTransactionAnnotationParser
have been updated accordingly to ensure that interfaces are not
unintentionally searched in the @Transactional resolution process.
This commit also introduces additional tests and updates TODOs for
SPR-12738.
Issue: SPR-12944, SPR-12738
Prior to this commit, the search algorithm used by the
findAnnotation(Method, Class) method in AnnotationUtils only found
direct annotations or direct meta-annotations (i.e., one level of
meta-annotations).
This commit reworks the search algorithm so that it supports arbitrary
levels of meta-annotations on methods. To make this possible, a new
findAnnotation(AnnotatedElement, Class) method has been introduced in
AnnotationUtils.
This fix also allows for the @Ignore'd tests in
TransactionalEventListenerTests to be re-enabled.
Issue: SPR-12941
- The exception message now mentions lacking to-Object method as well.
- Documented explicit lacking support for toString() for conversions.
- Introduced dedicated has*() methods for greater clarity and to reduce
code duplication.
- Static factory methods (i.e., of, from, valueOf) are now supported for
conversion to a String.
- Now correctly using @Test(expected=...) where appropriate.
- Renamed DefaultConversionTests to DefaultConversionServiceTests.
- Moved all tests related to DefaultConversionService from
GenericConversionServiceTests to DefaultConversionServiceTests.
- No longer printing to System.out.
- Removed all duplicate instantiation of conversion services.
- Now using Java 8 streams to simplify implementations of custom test
converters. Also using streams in tests where appropriate.
This commit introduces support for HTTP byte ranges in the
ResourceHttpRequestHandler. This support consists of a number of
changes:
- Parsing of HTTP Range headers in HttpHeaders, using a new HttpRange
class and inner ByteRange/SuffixByteRange subclasses.
- MIME boundary generation moved from FormHttpMessageConverter to
MimeTypeUtils.
- writePartialContent() method introduced in ResourceHttpRequestHandler,
handling the byte range logic
- Additional partial content tests added to
ResourceHttpRequestHandlerTests.
Issue: SPR-10805
Covers ReflectionUtils.doWithMethods as well as affected annotation post-processors.
Includes an extension of MethodMetadata for the detection of @Bean default methods.
Issue: SPR-12822
Issue: SPR-10919
Prior to this commit, the implementation of equals() in EncodedResource
was based solely on the resource and encoding. Thus, if a Charset were
specified instead of an encoding, invocations of equals() would not
work as expected.
This commit addresses this issue by including the charset in the
implementation of equals() and introducing corresponding tests in a new
EncodedResourceTests class. Furthermore, this commit makes
EncodedResource immutable and updates all Javadoc to reflect support
for the encoding and charset properties.
Issue: SPR-12767
This commit ensures Resources have consistent, non-empty, meaningful
implementations for getDescription(), thus ensuring that calls to
toString() (e.g., in log statements) no longer return an empty String.
This commit also polishes the Javadoc for various Resource
implementations.
Add StreamConverter to provide full support for converting
java.util.stream.Stream instances to and from collections or arrays.
Also attempt to convert the element type if necessary.
StreamConverter is registered by default in the DefaultConversionService
as long as Java8 is available.
Issue: SPR-12175
Previously, the `@Order` annotation was managed in an inconsistent way
when placed at the implementation level. For simple beans, it was
discovered properly but wasn't for beans requiring a proxy.
OrderComparator.SourceProvider now explicitly allows to return several
order sources; the default implementation returns not only the factory
method (if any) but also the target class if it happens to be different
from the class of the bean.
Issue: SPR-12636
Prior to this change, the ShallowEtagHeaderFilter would use a
ResizableByteArrayOutputStream to internally write data and calculate
the ETag. While that implementation is faster than the regular
ByteArrayOutputStream (since it has a better strategy for growing the
internal buffer), a lot of buffer copying/writing still happens.
This change adds a new FastByteArrayOutputStream implementation that
internally uses a LinkedList<Byte[]> to store the content. So when
writing bytes to that OutputStream implementation, new byte[] are
added to the list when the previous ones are full. This saves most
of the instantiating/copying operations.
Note that new methods were added in DigestUtils to allow usage of
Streams instead of byte[], which is more efficient in our case.
Fixes#653
Issue: SPR-12081
This commit introduces test methods in CollectionFactoryTests that
demonstrate how the APIs for createCollection() and createMap() are not
type-safe, specifically regarding the use of generics, raw types, and
casting.
SPR-12483 introduced automatic type conversion support for EnumSet and
EnumMap. However, the corresponding changes in CollectionFactory
contradict the existing contract for the "create approximate" methods
by creating a copy of the supplied set or map, thereby potentially
including elements in the returned collection when the returned
collection should in fact be empty.
This commit addresses this issue by ensuring that the collections
returned by createApproximateCollection() and createApproximateMap()
are always empty.
Furthermore, this commit improves the Javadoc throughout the
CollectionFactory class.
Issue: SPR-12533
This commit introduces test methods in CollectionFactoryTests that
demonstrate how the APIs for createApproximateCollection() and
createApproximateMap() are not type-safe, specifically regarding the use
of generics, raw types, and casting.
JUnit 4.12 created a 'public' version of the previously 'internal'
AssumptionViolatedException.
This commit upgrades Spring's Assume class to use this new public
version.
This commit introduces superfluous casts in CollectionFactory to
address a bug in Eclipse 4.4.1 that prevents the code from compiling
within Eclipse. Specifically, without these casts Eclipse displays the
following error for use of the EnumSet.copyOf() and EnumSet.noneOf()
methods:
Type mismatch: cannot convert from EnumSet<Enum<Enum<E>>> to
Collection<E>
Prior to this commit, JOptCommandLinePropertySource prevented the
possibility of non-String option arguments. This effectively prevents
the use of JOpt's #ofType support (which allows specifying custom
argument types).
Now, non-String arguments are detected and converted to strings as
necessary. JOpt's #ofType now works as expected. A test has been added
to cover this case.
Prior to this commit, the ResolvableType static cache was holding a lot
of duplicates for simple types. We are using too much metadata to compute
the key when the class has no generic information. so setFoo(String foo)
and setBar(String bar) would result in two entries in the cache because
the TypeProvider is different. On a very simple application 65% of the
entries in the cache were duplicate.
When the type is a Class with no generic information, the ResolvableType
instance is a simple wrapper around it so we might just as well not cache
it at all as the cost of finding it back from the cache is higher than
creating that simple wrapper.
This commit adds an explicit check; if the type is a simple Class we just
return a "resolved" ResolvableType instance for it. On a few test cases,
this reduces the size of the cache by 85%
Issue: SPR-12275
Prior to this commit, `AntPathMatcher.extractPathWithinPattern` would
not process correctly `**` patterns and would only match *one* path
segment in the given path.
This commit changes `extractPathWithinPattern` to allow multiple path
segments to be matched against a single `**` pattern segment.
Issue: SPR-10515
Update PathMatchingResourcePatternResolver to include additional
protected methods that can be used by subclasses to optimize which
JARs are searched.
Issue: SPR-12231
Update SystemEnvironmentPropertySource to attempt optimized Map lookups
first, and only fall-back to the defensive SecurityManager safe-mode
if these fail.
Issue: SPR-12224
Per the Javadoc for the SocketUtils() constructor, SocketUtils can be
instantiated as a Spring Bean in XML configuration files; however,
SocketUtils is currently abstract which prevents such usage.
This commit removes the 'abstract' declaration thereby allowing
SocketUtils to be instantiated as a Spring bean.
Issue: SPR-12169
Prior to this commit, when there was a lot of entries in the
ResolvableType.cache HashMap, getting a simple value could
take a lot of time due to a lot of calls to ResolvableType.equals().
ResolvableType.equals() used this.type, getSource(),
this.variableResolver.getSource() and this.componentType, but
ResolvableType.hashCode() used only this.type.
With this commit, ResolvableType.hashCode() now uses the same
fields than ResolvableType.equals().
Performance on the spring-resolvabletype-benchmark project:
- 8000 us before this commit
- 120 us with this commit
Issue: SPR-12122
Rework the @PropertySource parsing logic recently changed in commit
7c608886 to deal with the same source appearing on a @Configuration
class and an @Import class.
Processing now occurs in a single sweep, with any previously added
sources being converted to a CompositePropertySource.
Issue: SPR-12115
Prior to this commit, there was no declarative mechanism for a custom
TestExecutionListener to be registered as a default
TestExecutionListener.
This commit introduces support for discovering default
TestExecutionListener implementations via the SpringFactoriesLoader
mechanism. Specifically, the spring-test module declares all core
default TestExecutionListeners under the
org.springframework.test.context.TestExecutionListener key in its
META-INF/spring.factories properties file, and third-party frameworks
and developers can contribute to the list of default
TestExecutionListeners in the same manner.
- AbstractTestContextBootstrapper uses the SpringFactoriesLoader to
look up the class names of all registered default
TestExecutionListeners and sorts the instantiated listeners using
AnnotationAwareOrderComparator.
- DefaultTestContextBootstrapper and WebTestContextBootstrapper now
rely on the SpringFactoriesLoader mechanism for finding default
TestExecutionListeners instead of hard coding fully qualified class
names.
- To ensure that default TestExecutionListeners are registered in the
correct order, each can implement Ordered or declare @Order.
- AbstractTestExecutionListener and all default TestExecutionListeners
provided by Spring now implement Ordered with appropriate values.
- Introduced "copy constructors" in MergedContextConfiguration and
WebMergedContextConfiguration
- SpringFactoriesLoader now uses AnnotationAwareOrderComparator
instead of OrderComparator.
Issue: SPR-11466
Replace references to the old RFC 2616 (HTTP 1.1) with references
to the new RFCs 7230 to 7235.
This commit also deprecates:
- HttpStatus.USE_PROXY
- HttpStatus.REQUEST_ENTITY_TOO_LARGE in favor of HttpStatus.PAYLOAD_TOO_LARGE
- HttpStatus.REQUEST_URI_TOO_LONG in favor of HttpStatus.URI_TOO_LONG
Issue: SPR-12067
Prior to this commit, given an enum which implements some interface,
GenericConversionService would select the String -> Enum converter even
if a converter for String -> SomeInterface was registered. This also
affected converters that were registered for String ->
SomeBaseInterface, when SomeInterface extended SomeBaseInterface.
This change modifies the behavior of the private method
getClassHierarchy() by placing Enum.class as late as possible, pretty
much the same way as Object.class is handled.
Issue: SPR-12050
Make it possible to use a ListenableFuture with Java 8
lambda expressions, using a syntax like
listenableFuture.addCallback(() -> ..., () -> ...);
Issue: SPR-11820
In order to be able to use separators like "." (used by default
by most broker relays) instead of "/" for destination patterns
handling, the PathMatcher used in spring-messaging can now
be customized easily thanks to XML websocket namespace
or JavaConfig.
AntPathMatcher has been updated in order to use the configured path
separator instead of an hardcoded "/" for path concatenation.
Extension handling is now disabled when the "." separator is configured.
Issue: SPR-11660
This is analogous to what the JVM does for cases where the annotation type itself isn't present on the classpath. We're effectively extending that policy to values referenced within an annotation declaration.
Issue: SPR-11874
This change modifies the SettableListenableFuture implementation to use
internally a ListenableFutureTask created with a "settable" Callable.
Issue: SPR-11614
A SettableListenableFuture implementation of Spring's ListenableFuture
The class is inspired by Google Guava’s
com.google.common.util.concurrent.SettableFuture, but this
implementation uses ReentrantReadWriteLock and CountDownLatch
internally to handle thread synchronization.
Issue: SPR-11614
After this change, java.util.Optional is supported with @RequestParam,
@RequestHeader, and @MatrixVariable arguments in Java 8. When Optional
is used the required flag is effectively ignored.
Issue: SPR-11829
Prior to this commit, StringUtils#trimAllWhitespace(String str) was
unecessary slower. Using sb.deleteCharAt(index) leads to a complete
copy of the char[]
Prior to this commit, AntPathMatcher had been refactored for SPR-6741.
During that process, a key feature has been removed:
When comparing two patterns, pattern elements (*, {}, etc) are counted
to score those patterns. When a pattern ends with ".*", the ending
wildcard should not be counted against pattern elements for this
pattern.
This commit reintroduces that behavior.
Issue: SPR-6741
Prior to this commit, "**" and "*" pattern elements had
the same priority when comparing two patterns.
So when comparing several patterns, the computed order was:
1- /hotels/{hotel}/bookings/{booking}
2- /hotels/**
3- /hotels/{hotel}/bookings/{booking}/customer/{customer}
This commit updates the comparator so that patterns ending
with "**" (a.k.a "catch-all" patterns) are less specific than
the others; in the previous example, the 2nd pattern would
then end up last.
This commit also optimizes the comparator implementation.
Issue: SPR-6741
Includes support for arbitrary deep nesting levels in DependencyDescriptor's getDependencyType() and MethodParameter's getNestedParameterType().
Issue: SPR-11833
This commit introduces OrderProvider and OrderProviderComparator, two
interfaces designed to externalize how a collection of element is sorted
according to their order value.
FactoryAwareOrderProvider is an OrderProvider implementation that knows
about the objects to order and the corresponding BeanFactory instance.
This allows to retrieve additional metadata about the actual instances
to sort, such as its factory method.
A @Bean method can now holds an additional @Order to define the order
value that this bean should have when injected as part of a collection
or array.
Issue: SPR-11310
This commit separates the BackOff configuration from an actual
execution. BackOffExecution now contains all the state of a
particular execution and BackOff is only meant to start (i.e.
create) a new execution.
The method "reset" has been removed as its no longer necessary:
when an execution does not need to be used for a given operation
anymore it can be simply discarded.
Issue: SPR-11746
Prior to this commit, DefaultMessageListenerContainer was recovering
on failure using a fixed time interval, potentially in an infinite way.
This commit adds an extra "backoff" property to the container that
permits to fine tune the recovery interval using a BackOff instance.
FixedBackOff provides a fixed interval between two attempts and a
maximum number of retries. ExponentialBackOff increases an initial
interval until a maximum interval has been reached. A BackOff instance
can return a special "STOP" time value that indicates that no further
attemps should be made. DefaultMessageListenerContainer uses this
value to stop the container.
protected method "sleepInbetweenRecoveryAttempts" has been renamed
to "applyBackOff" and now returns a boolean that indicate if the
back off has been applied and a new attempt should now be made.
Issue: SPR-11746
Animal sniffer provides tools to assist verifying that classes
compiled with a newer JDK are compatible with an older JDK.
This integratesthe latest version of the tool (1.11) that
permits the use of custom annotations. Added @UsesJava7,
@UsesJava8 and @UsesSunHttpServer and annotated the few places
where we rely on a specific environment.
The verification process can be invoked by running the 'sniff'
task.
Issue: SPR-11604
polishing
Prior to this commit, invoking the getMergedAnnotationAttributes()
method in AnnotationReadingVisitorUtils resulted in mutation of the
internal state of the ASM-based annotation metadata supplied to the
method.
This commit fixes this issue by making a copy of the original
AnnotationAttributes for the target annotation before merging attribute
values from the meta-annotation hierarchy.
This commit also introduces a slight performance improvement by
avoiding duplicate processing of the attributes of the target
annotation.
Issue: SPR-11710
This commit adds support for the JSR-107 cache annotations alongside
the Spring's cache annotations, that is @CacheResult, @CachePut,
@CacheRemove and @CacheRemoveAll as well as related annotations
@CacheDefaults, @CacheKey and @CacheValue.
Spring's caching configuration infrastructure detects the presence of
the JSR-107 API and Spring's JCache implementation. Both
@EnableCaching and the cache namespace are able to configure the
required JCache infrastructure when necessary. Both proxy mode
and AspectJ mode are supported.
As JSR-107 permits the customization of the CacheResolver to use for
both regular and exception caches, JCacheConfigurer has been
introduced as an extension of CachingConfigurer and permits to define
those.
If an exception is cached and should be rethrown, it is cloned and
the call stack is rewritten so that it matches the calling thread each
time. If the exception cannot be cloned, the original exception is
returned.
Internally, the interceptors uses Spring's caching abstraction by default
with an adapter layer when a JSR-107 component needs to be called.
This is the case for CacheResolver and CacheKeyGenerator.
The implementation uses Spring's CacheManager abstraction behind the
scene. The standard annotations can therefore be used against any
CacheManager implementation.
Issue: SPR-9616
This commit rationalizes the use of @Order so that the standard
@Priority annotation can be used instead. The handling of both
annotations are now defined in OrderUtils.
This also updates the link to the JavaEE API so that we refer to
JavaEE7 instead of JavaEE6.
Issue: SPR-11639
Improved the SAX to StAX (and vice-versa) bridge exposed via StaxUtils.
The old integration had some issues with namespace declaration
attributes, brought to light in a XMLUnit upgrade.
Issue: SPR-11549
Changes introduced in conjunction with issue SPR-11475 altered the
behavior of StandardAnnotationMetadata such that annotations could be
detected on superclasses, specifically in the case where the
AnnotatedElementUtils.getAllAnnotationAttributes() method is invoked to
obtain multiple annotations of the same type (on the lowest level in the
class hierarchy), as is the case for @Profile and @Conditional.
This commit partially reverts these changes as follows:
- All methods in AnnotatedElementUtils now set the
traverseClassHierarchy to false, thereby effectively reverting the
changes made in commit 1d30bf83a0.
Note, however, that the changes made to AnnotationUtils remain in
place.
- Introduced tests in AnnotationMetadataTests that verify behavior
present in Spring Framework 4.0.2 and earlier.
- Updated tests in AnnotatedElementUtilsTests so that they pass against
the reverted changes (i.e., align with the behavior present in Spring
Framework 4.0.2 and earlier).
- Refined Javadoc in AnnotationMetadata with regard to annotations
being "present" vs. "defined".
- Refined Javadoc in AnnotatedTypeMetadata.
Issue: SPR-11475, SPR-11595
Prior to this commit, the ShallowEtagHeaderFilter did not use the
content length given by the content generator to set the
ByteArrayOutputStream's buffer size.
This can lead to performance issues for large content since the buffer
grows as the content is being written.
This commit adds a new ByteArrayOutputStream variant called
ResizableByteArrayOutputStream. This implementation has public methods
for modifying the internal buffer size and does not synchronize on
buffer access.
This commit also make use of this new variant in
ShallowEtagHeaderFilter.
Issue: SPR-8271
- AnnotationAttributesReadingVisitor no longer processes annotations
from the java.lang.annotation package.
- Simplified logic in AnnotationReadingVisitorUtils
getMergedAnnotationAttributes().
Issue: SPR-11574
Prior to this commit, the codebase was using a mix of log4j.xml
and log4j.properties for test-related logging configuration. This
can be an issue as log4j takes the xml variant first when looking
for a default bootstrap configuration.
In practice, some modules declaring the properties variant were
taking the xml variant configuration from another module.
The general structure of the configuration has also been
harmonized to provide a standard console output as well as an
easy way to enable trace logs for the current module.
Prior to this commit, Spring supported meta-annotation attribute
overrides in custom composed annotations with reflection-based
annotation processing but not with ASM-based annotation processing.
This commit ensures that meta-annotation attribute overrides are
supported in AnnotationMetadataReadingVisitor.getAnnotationAttributes().
Issue: SPR-11574
Prior to this commit, AnnotationAttributesReadingVisitor treated Class
annotation attributes as Strings instead of Classes. As a result,
look-ups for Class attributes in meta-annotations failed with an
IllegalArgumentException.
This commit fixes this issue by consistently treating Class attributes
as Classes in AnnotationAttributesReadingVisitor.
Issue: SPR-11557
This commit continues the work in the previous commit as follows:
- Introduced an exception hierarchy for exceptions related to SQL
scripts, with ScriptException as the base.
- CannotReadScriptException and ScriptStatementFailedException now
extend ScriptException.
- Introduced ScriptParseException, used by ScriptUtils.splitSqlScript().
- DatabasePopulatorUtils.execute() now explicitly throws a
DataAccessException.
- Polished Javadoc in ResourceDatabasePopulator.
- Overhauled Javadoc in ScriptUtils and documented all constants.
- Added missing @author tags for original authors in ScriptUtils and
ScriptUtilsTests.
- ScriptUtils.splitSqlScript() now asserts preconditions.
- Deleted superfluous methods in ScriptUtils and changed method
visibility to private or package private as appropriate.
- Deleted the ScriptStatementExecutor introduced in the previous
commit; ScriptUtils.executeSqlScript() now accepts a JDBC Connection;
JdbcTestUtils, AbstractTransactionalJUnit4SpringContextTests, and
AbstractTransactionalTestNGSpringContextTests now use
DatabasePopulatorUtils to execute a ResourceDatabasePopulator instead
of executing a script directly via ScriptUtils.
- Introduced JdbcTestUtilsIntegrationTests.
Issue: SPR-9531
Also uses addAll instead of iteration over untyped collection now, supporting optimized addAll in target collection type, and avoids repeated getElementTypeDescriptor calls.
Issue: SPR-11479
Fixed through falling back to the raw parameter type in the TypeDescriptor(MethodParameter) constructor, properly detecting the vararg array even in case of an unresolvable type variable, and through restoring getElementTypeDescriptor's original behavior for arrays, i.e. always returning a non-null descriptor.
Issue: SPR-11494
The previous commit introduced a dependency on
Class.getDeclaredAnnotation() which is a Java 8 API.
This commit refactors AnnotationUtils.findAnnotation(Class, Class, Set)
to use Class.getAnnotation() in conjunction with
isAnnotationDeclaredLocally() in order to achieve the same desired
behavior.
Issue: SPR-11475
Prior to this commit, the implementations of findAnnotation() in
AnnotationUtils and getAnnotationAttributes() in AnnotatedElementUtils
favored inherited annotations and inherited composed annotations over
composed annotations that are declared closer to the starting class
passed to these methods.
This commit addresses this issue as follows:
- Refactored AnnotationUtils to use getDeclaredAnnotation() and
getDeclaredAnnotations() instead of getAnnotation() and
getAnnotations() where appropriate.
- AnnotatedElementUtils.doProcess() supports a traverseClassHierarchy
flag to control whether the class hierarchy should be traversed,
using getDeclaredAnnotations() instead of getAnnotations() if the
flag is true.
- Overhauled Javadoc in AnnotatedElementUtils.
Issue: SPR-11475
This commit introduces a new isInJavaLangAnnotationPackage(Annotation)
method in AnnotationUtils. This method is now used in AnnotationUtils,
AnnotatedElementUtils, and MetaAnnotationUtils to ensure that search
algorithms do no search for meta-annotations on annotations in the
"java.lang.annotation" package.
The following are some empirical results from this change:
- The number of times that the findAnnotation(Class,Class,Set) method in
AnnotationUtils is recursively invoked while executing
AnnotationUtilsTests drops from 51 to 29.
- The number of times that the process(AnnotatedElement) method in
AnnotationUtils.AnnotationCollector is recursively invoked while
executing AnnotationUtilsTests.getRepeatableFromMethod() drops
from 16 to 2.
- The number of times that the doProcess() method in
AnnotatedElementUtils is recursively invoked while executing the
"getAnnotationAttributes() On MetaCycleAnnotatedClass with missing
target meta-annotation" test in AnnotatedElementUtilsTests drops
from 23 to 5.
- The number of times that the findAnnotationDescriptor(Class,Set,Class)
method in MetaAnnotationUtils is recursively invoked while executing
the "findAnnotationDescriptor() on MetaCycleAnnotatedClass with
missing target meta-annotation" test in MetaAnnotationUtilsTests drops
from 16 to 8.
Issue: SPR-11483
Prior to this commit, AnnotationUtils.findAnnotation(Class, Class)
claimed to recursively search through annotations; however, only one
level of annotations was supported by the algorithm.
This commit alters the search algorithm so that nested meta-annotations
(i.e., meta-annotations on meta-annotations) are also supported.
Issue: SPR-11448
Update ConcurrentReferenceHashMap to protect against references that
have been garbage collected but for some reason do not appear as a
`pollForPurge` result.
Also added purgeUnreferencedEntries() method to allow for programmatic
cleanup.
Issue: SPR-11440
Prior to this commit several test classes named "*Test" were not
recognized as tests by the Gradle build. This is due to the configured
inclusion of '**/*Tests.*' which follows Spring's naming convention for
test classes.
This commit addresses this issue by:
- Renaming real test classes consistently to "*Tests".
- Renaming internal test classes to "*TestCase".
- Renaming @WebTest to @WebTestStereotype.
- Disabling broken tests in AnnoDrivenStaticEntityMockingControlTest.
- Modifying the Gradle build configuration so that classes ending in
either "*Tests" or "*Test" are considered test classes.
Issue: SPR-11384
JOpt 4.6 redeclared its nonOptionArguments() method from List<String> to List<?>, requiring us to select String arguments only as we do for regular option values already.
Issue: SPR-11359
This in particular allows for specifying "spring.getenv.ignore" and "spring.beaninfo.ignore" in a local way within the application, in case that JVM-level system properties are locked.
Issue: SPR-9014
Issue: SPR-11297
Update ResolvableType to unwrap Serialization wrapped TypeVariables
before calling the equals method.
This protects against the recent change in OpenJDK 8 (build 124)
which changed the TypeVariableImpl equals method such that it only
matches against other TypeVariableImpl instances.
Issue: SPR-11342
Change SerializableTypeWrapper proxies to directly call equals() methods
on the underlying Type, rather than possibly generating more wrappers.
This should help to improve performance, especially as the equals()
method is called many times when the ResolvableType cache is checked.
Issue: SPR-11335
Provided overloaded versions of `forField` and `forMethodParameter` that
accept a `ResolvableType` implementation type (as opposed to a Class).
Primarily added to allow resolution against implementation types that
have been created programmatically using `forTypeWithGenerics`.
Issue: SPR-11218
Also introduced a default ZonedDateTime-Calendar converter which is not covered by the default convention due to the 'from' method only being defined on GregorianCalendar.
Issue: SPR-11259
This turned out to be a bug in the ASM-based AnnotationMetadata implementation where has/getAnnotatedMethods didn't consider meta-annotations., in contrast to its StandardAnnotationMetadata sibling.
Issue: SPR-10488
This is necessary for source compatibility with existing callers, such as code found in Spring Integration: e.g. passing the arrayToList result into a typed HashSet constructor.
Apply consistent styling to new classes introduced in Spring 4.0.
- Javadoc line wrapping, whitespace and formatting
- General code whitespace
- Consistent Assert.notNull messages
Fix a variety of typos throughout the project, primarily in
comments (javadoc or otherwise) but also in a handful of log messages
and a couple exception messages.
ISSUE: SPR-11123
Fix remaining Java compiler warnings, mainly around missing
generics or deprecated code.
Also add the `-Werror` compiler option to ensure that any future
warnings will fail the build.
Issue: SPR-11064
- Added explicit reference to “get” and “find” lookup types in the
class-level Javadoc.
- Updated documentation for the underlying algorithms in
findAnnotation(Method,Class) and findAnnotation(Class,Class) in line
with the status quo.
- Reverted recent changes to findAnnotationDeclaringClass() by removing
meta-annotation support in order to maintain backwards compatibility
with previous releases.
Prior to this commit, the getValue(Annotation, String) method in
AnnotationUtils failed to retrieve the value of the desired annotation
attribute if the annotation itself was not public -- for example if the
annotation was declared as package private.
This commit addresses this issue by ensuring that getValue(Annotation,
String) uses reflection to make the desired annotation attribute method
accessible before attempting to invoke it to retrieve the value.
Issue: SPR-11104
Since @Bean methods are never used with externally specified constructor argument values but rather just with autowiring, the non-lenient constructor resolution mode is appropriate in case of an overloaded @Bean method, not performing any type difference weight checks. This change includes a refinement of Spring's existing non-lenient constructor resolution (which needs to be explicitly turned on and is therefore not well tested), narrowing the conditions for the ambiguity check (only in case of the same number of arguments and not for overridden methods).
Issue: SPR-10988
Update MatchAlwaysTransactionAttributeSource.getTransactionAttribute
to allow a null method argument. Passing a null method is not
recommended and is not indicated as valid in the Javadoc, however,
this was allowed in previous versions of Spring.
Issue: SPR-11048
Update ResolvableType to check that the resolved component type from
a generic array is not null before attempting to use it to generate the
resolved array class.
Issue: SPR-11044
In particular, do not apply them to GroovyObject methods and other kinds of synthetic methods in language runtimes. The only exception are bridge methods since those do eventually point to a user-level generic method.
Issue: SPR-10803
Introduced a "setCachePatterns(boolean)" method for explicit configuration, a default turnoff threshold at 65536 entries (at which point we're deciding that caching isn't worthwhile because patterns are unlikely to be reoccurring often enough), and an "AntPathStringMatcher getStringMatcher(String pattern)" template method.
Issue: SPR-10803
Spring 3.0 already allows component stereotypes to be used in a
meta-annotation fashion, for example by creating a custom
@TransactionalService stereotype annotation which combines
@Transactional and @Service in a single, reusable, application-specific
annotation. However, the Spring TestContext Framework (TCF) currently
does not provide any support for test-related annotations to be used as
meta-annotations.
This commit overhauls the TCF with regard to how annotations are
retrieved and adds explicit support for the following annotations to be
used as meta-annotations in conjunction with the TCF.
- @ContextConfiguration
- @ContextHierarchy
- @ActiveProfiles
- @DirtiesContext
- @IfProfileValue
- @ProfileValueSourceConfiguration
- @BeforeTransaction
- @AfterTransaction
- @TransactionConfiguration
- @Rollback
- @TestExecutionListeners
- @Repeat
- @Timed
- @WebAppConfiguration
Note that meta-annotation support for @Transactional was already
available prior to this commit.
The following is a summary of the major changes included in this commit.
- Now using AnnotationUtils.getAnnotation() instead of
Class.getAnnotation() where appropriate in the TestContext Framework.
- Now using AnnotationUtils.findAnnotation() instead of
Class.isAnnotationPresent() where appropriate in the TestContext
Framework.
- Introduced findAnnotationPrefersInteracesOverLocalMetaAnnotations() in
AnnotationUtilsTests in order to verify the status quo.
- AnnotationUtils.findAnnotationDeclaringClass() and
AnnotationUtils.findAnnotationDeclaringClassForTypes() now support
meta annotations.
- Introduced MetaAnnotationUtils and AnnotationDescriptor in the
spring-test module.
- Introduced UntypedAnnotationDescriptor in MetaAnnotationUtils.
- Introduced findAnnotationDescriptorForTypes() in MetaAnnotationUtils.
- ContextLoaderUtils now uses MetaAnnotationUtils for looking up
@ActiveProfiles as a potential meta-annotation.
- TestContextManager now uses MetaAnnotationUtils for looking up
@TestExecutionListeners as a potential meta-annotation.
- DirtiesContextTestExecutionListener now uses AnnotationUtils for
looking up @DirtiesContext as a potential meta-annotation.
- Introduced DirtiesContextTestExecutionListenerTests.
- ProfileValueUtils now uses AnnotationUtils for looking up
@IfProfileValue and @ProfileValueSourceConfiguration as potential
meta-annotations.
- @BeforeTransaction and @AfterTransaction now support ANNOTATION_TYPE
as a target, allowing them to be used as meta-annotations.
- TransactionalTestExecutionListener now uses AnnotationUtils for
looking up @BeforeTransaction, @AfterTransaction, @Rollback, and
@TransactionConfiguration as potential meta-annotations.
- Introduced TransactionalTestExecutionListenerTests.
- @Repeat and @Timed now support ANNOTATION_TYPE as a target, allowing
them to be used as meta-annotations.
- SpringJUnit4ClassRunner now uses AnnotationUtils for looking up
@Repeat and @Timed as potential meta-annotations.
- Moved all remaining logic for building the MergedContextConfiguration
from the DefaultTestContext constructor to
ContextLoaderUtils.buildMergedContextConfiguration().
- Verified meta-annotation support for @WebAppConfiguration and
@ContextConfiguration.
Issue: SPR-7827
Add getSource() method to ResolvableType and TypeDescriptor allowing
access to the underlying source field or method parameter when possible.
Primarily added to provide access to additional type information or
meta-data that alternative JVM languages may provide.
Issue: SPR-10887
DefaultListableBeanFactory performs a fallback check for autowire candidates now, which GenericTypeAwareAutowireCandidateResolver implements to accept raw type matches if the target class has unresolvable type variables. Full generic matches are still preferred; the BeanFactory will only start looking for fallback matches if the first pass led to an empty result.
Issue: SPR-10993
Issue: SPR-11004
Support repeatable @PropertySource annotations in Java 8 and add
@PropertySources container annotation for Java 6/7. Also add an
ignoreResourceNotFound attribute to @PropertySource allowing missing
property resources to be silently ignored.
This commit also introduces some generally useful methods to
AnnotationUtils for working with @Repeatable annotations.
Issue: SPR-8371
The key contract is MvcUrls. An instance is automatically created with
the Spring MVC namespace and the MVC Java config but can also be easily
created in any configuration.
Some example tests can be found in DefaultMvcUrlsTests.
Issue: SPR-10665, SPR-8826
MvcUriComponentsBuilder allows creating URIs that point to Spring MVC
controller methods annotated with @RequestMapping. It builds them by
exposing a mock method invocation API similar to Mockito, records the
method invocations and thus builds up the URI by inspecting the mapping
annotations and the parameters handed into the method invocations.
Introduced a new SPI UriComponentsContributor that should be implemented
by HandlerMethodArgumentResolvers that actually contribute path segments
or query parameters to a URI. While the newly introduced
MvcUriComponentsBuilder looks up those UriComponentsContributor instances
from the MVC configuration.
The MvcUriComponentsBuilderFactory (name to be discussed - MvcUris maybe?)
prevents the multiple lookups by keeping the UriComponentsBuilder
instances in an instance variable. So an instance of the factory could
be exposed as Spring bean or through a HandlerMethodArgumentResolver to
be injected into Controller methods.
Issue: SPR-10665, SPR-8826
Refactor TypeDescriptor to use ResolvableType in order to retain full
generic type information, in the process fixing MultiValueMap support
in MapToMapConverter.
Issue: SPR-9499
- Support for serialization
- Allow programmatic creation of an array from a given component type
- Allow programmatic creation with given generics
- Extract generics from Class types using Class.getTypeParameters()
- Move TypeVariableResolver to an inner class (and make method private)
- Refine 'resolve()' algorithm
Issue: SPR-10973
- Now avoiding NullPointerExceptions in GenericTypeResolver's
resolveReturnTypeForGenericMethod() in case the supplied ClassLoader
is null.
- AutowireUtils.resolveReturnTypeForFactoryMethod() now properly
asserts that the supplied ClassLoader is not null.
- Fixed copy-n-paste errors in Javadoc for
AutowireUtils.resolveReturnTypeForFactoryMethod().
Issue: SPR-10411
Includes revisions of MethodParameter and DependencyDescriptor (in particular towards a reference to the containing class). Also refines several ResolvableType method signatures.
Issue: SPR-9965
We're consistently resolving class names now, and the entire algorithm moved from GenericTypeResolver to the internal AutowireUtils helper in the bean factory package.
Issue: SPR-10411
Refactor AbstractMessageConverterMethodArgumentResolver and
BridgeMethodResolver to use ResolvableType in preference to deprecated
GenericTypeResolver calls.
Issue: SPR-10980
Add a new ResolvableType Class which encapsulates java.lang.reflect.Type,
providing access to supertypes, interfaces and generic parameters along
with the ability to ultimately resolve to a java.lang.Class.
ResolvableTypes may be obtained from fields, method parameters, method
returns, classes or directly from a java.lang.reflect.Type. Most methods
will themselves return ResolvableTypes, allowing easy navigation.
For example:
private HashMap<Integer, List<String>> myMap;
public void example() {
ResolvableType t = ResolvableType.forField(
getClass().getDeclaredField("myMap"));
t.getSuperType(); // AbstractMap<Integer, List<String>>;
t.asMap(); // Map<Integer, List<String>>
t.getGeneric(0).resolve(); // Integer
t.getGeneric(1).resolve(); // List
t.getGeneric(1); // List<String>
t.resolveGeneric(1, 0); // String
}
Issue: SPR-10973
A few noteworthy minor changes: LocaleContext.getLocale() may return null in special cases (not by default), which our own accessing classes are able to handle now. If there is a non-null TimeZone user setting, we're exposing it to all collaborating libraries, in particular to JSTL, Velocity and JasperReports. Our JSR-310 and Joda-Time support falls back to checking the general LocaleContext TimeZone now, adapting it to their time zone types, if no more specific setting has been provided. Our DefaultConversionService has TimeZone<->ZoneId converters registered. And finally, we're using a custom parseTimeZoneString method now that doesn't accept the TimeZone.getTimeZone(String) GMT fallback for an invalid time zone id anymore.
Issue: SPR-1528
Added extension to Future with capabilities for registering callbacks
when the future is complete.
- Added ListenableFuture, ListenableFutureCallback,
ListenableFutureCallbackRegistry, and ListenableFutureTask.
- Using ListenableFuture in AsyncRestOperations/AsyncRestTemplate.
- Added AsyncListenableTaskExecutor, implemented in
SimpleAsyncTaskExecutor.
- Added FutureAdapter and ListenableFutureAdapter.