Skip to content

Introduce unified support for declaring and looking up annotation attribute aliases [SPR-11512] #16137

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
3 of 4 tasks
spring-projects-issues opened this issue Mar 4, 2014 · 2 comments
Assignees
Labels
in: core Issues in core modules (aop, beans, core, context, expression) type: enhancement A general enhancement
Milestone

Comments

@spring-projects-issues
Copy link
Collaborator

spring-projects-issues commented Mar 4, 2014

Sam Brannen opened SPR-11512 and commented

Status Quo

Limited support for annotation attribute aliases already exists in the Spring Framework but is scattered across various modules. Currently, the following annotations are known to support aliases:

  • @ManagedResource
  • @ActiveProfiles
  • @ContextConfiguration
  • @Sql
  • @TestExecutionListeners
  • @TestPropertySource
  • @ControllerAdvice

Goal

The goal of this issue is to introduce unified support for declaring and looking up annotation attribute aliases (within a given annotation).


Deliverables

All annotations introduced in conjunction with this issue must reside in the org.springframework.core.annotation package.

  1. Introduce an annotation that can be declared on annotation attributes to indicate that the given attribute is an alias for another attribute of the same type within the same annotation class.
    • Proposed name: @AliasFor
  2. Consider introducing another annotation to be used on the aliased attribute itself in order to provide a two-way link between all such aliases.
    • Proposed name: @AliasedBy
  3. Extract code from the TestContext framework that is responsible for handling the look-up of annotation aliases and incorporate this code in a generic fashion in AnnotationUtils and AnnotatedElementUtils as appropriate.
    • This new look-up mechanism must be based on the annotation introduced in deliverable Spring core JMS pom.xml #1.
    • If multiple values for an aliased attribute are present in a declared annotation, an AnnotationConfigurationException must be thrown indicating that only one attribute for an aliased attribute may be specified in a concrete instance of the given annotation.
    • See also the current implementations for attribute aliases related to @ControllerAdvice and @ManagedResource.
  4. Migrate all existing code that supports attribute aliases to use this new mechanism.

Example: Modified @ContextConfiguration Declaration

The following demonstrates how @ContextConfiguration could be rewritten to take advantage of the functionality proposed by this issue.

public @interface ContextConfiguration {

    @AliasedBy("locations")
    String[] value() default {};

    @AliasFor("value")
    String[] locations() default {};

    // ...
}

Affects: 4.0 GA

Issue Links:

@spring-projects-issues
Copy link
Collaborator Author

spring-projects-issues commented May 14, 2015

Sam Brannen commented

Current development work can be seen in my #16137 feature branch on GitHub.

Feel free to comment.

@spring-projects-issues
Copy link
Collaborator Author

Sam Brannen commented

Implemented as described in the comments for GitHub commit ca66e07:

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")

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: core Issues in core modules (aop, beans, core, context, expression) type: enhancement A general enhancement
Projects
None yet
Development

No branches or pull requests

2 participants