Sam Brannen

Polish and reorganize new-in-4.2 section

Polish annotation utility tests

Verify that SynthesizedAnnotation must be public

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

Introduce putIfAbsent() in AnnotationAttributes

Issue: SPR-13060

Merge from sbrannen/SPR-11512

  • SPR-11512:

    Support annotation attribute aliases and overrides via @AliasFor

Introduce SpringFailOnTimeout(Statement, Method) constructor

Introduce TestAnnotationUtils to reduce code duplication

Introduce TestContextManager cache in SpringClassRule

In order to simplify configuration of the SpringMethodRule and to ensure

that the correct TestContextManager is always retrieved for the

currently executing test class, this commit introduces a static

TestContextManager cache in SpringClassRule.

In addition, since it is not foreseen that SpringClassRule and

SpringMethodRule should be able to be subclassed, their internal methods

are now private instead of protected.

Issue: SPR-7731

Introduce JUnitTestingUtils to reduce code duplication

Merge from sbrannen/SPR-7731

  • SPR-7731:

    Introduce JUnit Rule alternative to SpringJUnit4ClassRunner

Support annotation attribute aliases and overrides via @AliasFor

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

  1. … 16 more files in changeset.

Document "present" terminology in AnnotationUtils

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

Use findAnnotationAttributes() where appropriate

This commit updates code that previously used getAnnotationAttributes()

in AnnotatedElementUtils to use findAnnotationAttributes(), where

appropriate.

Issue: SPR-12738

Favor local, composed annotations in AnnotatedElementUtils

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

Expound on inheritance semantics for @Conditional

Issue: SPR-11598

Document search scope in Ann*[Element]Utils

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

Add TODO re: FailOnTimeout.builder() & JUnit 4.12

Polish SpringJUnit4ClassRunner and related support classes

Fix broken AnnotationAttributesTests

Issue: SPR-13007

Merge pull request #797 from marschall/SPR-13007

  • SPR-13007:

    Avoid eager formatting in pre-condition checks

Assert pre-conditions in AopTestUtils

Issue: SPR-13005

Introduce AOP testing utilities

This commit introduces support in the spring-test module for obtaining a

reference to the underlying target object hidden behind one or more

proxies.

Specifically this commit introduces AopTestUtils with two methods:

  • getTargetObject(Object)

  • getUltimateTargetObject(Object)

Issue: SPR-13005

Polish Javadoc for AopUtils, Advised, & related classes

Introduce JUnit Rule alternative to SpringJUnit4ClassRunner

Since Spring Framework 2.5, support for integrating the Spring

TestContext Framework (TCF) into JUnit 4 based tests has been provided

via the SpringJUnit4ClassRunner, but this approach precludes the

ability for tests to be run with alternative runners like JUnit's

Parameterized or third-party runners such as the MockitoJUnitRunner.

This commit remedies this situation by introducing @ClassRule and @Rule

based alternatives to the SpringJUnit4ClassRunner. These rules are

independent of any Runner and can therefore be combined with

alternative runners.

Due to the limitations of JUnit's implementation of rules, as of JUnit

4.12 it is currently impossible to create a single rule that can be

applied both at the class level and at the method level (with access to

the test instance). Consequently, this commit introduces the following

two rules that must be used together.

  • SpringClassRule: a JUnit TestRule that provides the class-level

    functionality of the TCF to JUnit-based tests

  • SpringMethodRule: a JUnit MethodRule that provides the

    instance-level and method-level functionality of the TCF to

    JUnit-based tests

In addition, this commit also introduces the following new JUnit

Statements for use with rules:

  • RunPrepareTestInstanceCallbacks

  • ProfileValueChecker

Issue: SPR-7731

  1. … 25 more files in changeset.

Provide @Rule alternative to SpringJUnit4ClassRunner

Work In Progress: feature complete but in need of further documentation.

Issue: SPR-7731

  1. … 25 more files in changeset.

Provide @Rule alternative to SpringJUnit4ClassRunner

Work In Progress: feature complete but in need of further documentation.

Issue: SPR-7731

  1. … 6 more files in changeset.

Rename MethodBasedEvaluationContextTest to *Tests

Delete spring-context's dependency on spring-beans-groovy

Commit 5648fbfc3155ddf4ead7388cfd7bc9e90b86f9d8 introduced a

compile-time dependency on spring-beans-groovy in the spring-context

module which breaks the build on the CI server since the Animal Sniffer

task cannot find a JAR file for spring-beans-groovy.

This commit reverts that change so that the "sniffer" task once again

succeeds.

Support arbitrary levels of meta-annotations in TypeDescriptor

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

Polish Javadoc for MethodParameter