Document @AliasFor
Issue: SPR-11512
This commit is contained in:
@@ -24,18 +24,120 @@ import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* TODO Document @AliasFor.
|
||||
* {@code @AliasFor} is an annotation that is used to declare aliases for
|
||||
* annotation attributes.
|
||||
*
|
||||
* <h3>Usage Scenarios</h3>
|
||||
* <ul>
|
||||
* <li><strong>Aliases within an annotation</strong>: within a single
|
||||
* annotation, {@code @AliasFor} can be declared on a pair of attributes to
|
||||
* signal that they are interchangeable aliases for each other.</li>
|
||||
* <li><strong>Alias for attribute in meta-annotation</strong>: if the
|
||||
* {@link #annotation} attribute of {@code @AliasFor} is set to a different
|
||||
* annotation than the one that declares it, the {@link #attribute} is
|
||||
* interpreted as an alias for an attribute in a meta-annotation (i.e., an
|
||||
* explicit meta-annotation attribute override). This enables fine-grained
|
||||
* control over exactly which attributes are overridden within an annotation
|
||||
* hierarchy. In fact, with {@code @AliasFor} it is even possible to declare
|
||||
* an alias for the {@code value} attribute of a meta-annotation.</li>
|
||||
* </ul>
|
||||
*
|
||||
* <h3>Usage Requirements</h3>
|
||||
* <p>Like with any annotation in Java, the mere presence of {@code @AliasFor}
|
||||
* on its own will not enforce alias semantics. For alias semantics to be
|
||||
* enforced, annotations must be <em>loaded</em> via the utility methods in
|
||||
* {@link AnnotationUtils}. Behind the scenes, Spring will <em>synthesize</em>
|
||||
* an annotation by wrapping it in a dynamic proxy that transparently enforces
|
||||
* <em>attribute alias</em> semantics for annotation attributes that are
|
||||
* annotated with {@code @AliasFor}. Similarly, {@link AnnotatedElementUtils}
|
||||
* supports explicit meta-annotation attribute overrides when {@code @AliasFor}
|
||||
* is used within an annotation hierarchy. Typically you will not need to
|
||||
* manually synthesize annotations on your own since Spring will do that for
|
||||
* you transparently when looking up annotations on Spring-managed components.
|
||||
*
|
||||
* <h3>Implementation Requirements</h3>
|
||||
* <ul>
|
||||
* <li><strong>Aliases within an annotation</strong>:
|
||||
* <ol>
|
||||
* <li>Each attribute that makes up an aliased pair must be annotated with
|
||||
* {@code @AliasFor}, and the {@link #attribute} must reference the
|
||||
* <em>other</em> attribute in the pair.</li>
|
||||
* <li>Aliased attributes must declare the same return type.</li>
|
||||
* <li>Aliased attributes must declare a default value.</li>
|
||||
* <li>Aliased attributes must declare the same default value.</li>
|
||||
* <li>The {@link #annotation} attribute may remain set to the default,
|
||||
* although setting it to the declaring class for both attributes in the
|
||||
* pair is also valid.</li>
|
||||
* </ol>
|
||||
* </li>
|
||||
* <li><strong>Alias for attribute in meta-annotation</strong>:
|
||||
* <ol>
|
||||
* <li>The attribute that is an alias for an attribute in a meta-annotation
|
||||
* must be annotated with {@code @AliasFor}; the {@link #attribute} must
|
||||
* reference the aliased attribute in the meta-annotation; and the
|
||||
* {@link #annotation} must reference the meta-annotation.</li>
|
||||
* <li>Aliased attributes must declare the same return type.</li>
|
||||
* </ol>
|
||||
* </li>
|
||||
* </ul>
|
||||
*
|
||||
* <h3>Example: Aliases within an Annotation</h3>
|
||||
* <pre class="code"> public @interface ContextConfiguration {
|
||||
*
|
||||
* @AliasFor(attribute = "locations")
|
||||
* String[] value() default {};
|
||||
*
|
||||
* @AliasFor(attribute = "value")
|
||||
* String[] locations() default {};
|
||||
*
|
||||
* // ...
|
||||
* }</pre>
|
||||
*
|
||||
* <h3>Example: Alias for Attribute in Meta-annotation</h3>
|
||||
* <pre class="code"> @ContextConfiguration
|
||||
* public @interface MyTestConfig {
|
||||
*
|
||||
* @AliasFor(annotation = ContextConfiguration.class, attribute = "locations")
|
||||
* String[] xmlFiles();
|
||||
* }</pre>
|
||||
*
|
||||
* <h3>Spring Annotations Supporting Attribute Aliases</h3>
|
||||
* <p>As of Spring Framework 4.2, the following annotations within core
|
||||
* Spring have been updated to use {@code @AliasFor} to configure their
|
||||
* internal attribute aliases.
|
||||
* <ul>
|
||||
* <li>{@link org.springframework.jmx.export.annotation.ManagedResource}</li>
|
||||
* <li>{@link org.springframework.test.context.ActiveProfiles}</li>
|
||||
* <li>{@link org.springframework.test.context.ContextConfiguration}</li>
|
||||
* <li>{@link org.springframework.test.context.TestExecutionListeners}</li>
|
||||
* <li>{@link org.springframework.test.context.TestPropertySource}</li>
|
||||
* <li>{@link org.springframework.test.context.jdbc.Sql}</li>
|
||||
* <li>{@link org.springframework.web.bind.annotation.ControllerAdvice}</li>
|
||||
* <li>{@link org.springframework.web.bind.annotation.RequestMapping}</li>
|
||||
* </ul>
|
||||
*
|
||||
* @author Sam Brannen
|
||||
* @since 4.2
|
||||
* @see AnnotatedElementUtils
|
||||
* @see AnnotationUtils
|
||||
* @see AnnotationUtils#synthesizeAnnotation(Annotation, java.lang.reflect.AnnotatedElement)
|
||||
* @see SynthesizedAnnotation
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.METHOD)
|
||||
@Documented
|
||||
public @interface AliasFor {
|
||||
|
||||
/**
|
||||
* The name of the attribute that <em>this</em> attribute is an alias for.
|
||||
*/
|
||||
String attribute();
|
||||
|
||||
/**
|
||||
* The type of annotation in which the aliased {@link #attribute} is declared.
|
||||
* <p>Defaults to {@link Annotation}, implying that the aliased attribute is
|
||||
* declared in the same annotation as <em>this</em> attribute.
|
||||
*/
|
||||
Class<? extends Annotation> annotation() default Annotation.class;
|
||||
|
||||
}
|
||||
|
||||
@@ -17,10 +17,13 @@
|
||||
package org.springframework.core.annotation;
|
||||
|
||||
/**
|
||||
* Thrown by {@link AnnotationUtils} if an annotation is improperly configured.
|
||||
* Thrown by {@link AnnotationUtils} and <em>synthesized annotations</em>
|
||||
* if an annotation is improperly configured.
|
||||
*
|
||||
* @author Sam Brannen
|
||||
* @since 4.2
|
||||
* @see AnnotationUtils
|
||||
* @see SynthesizedAnnotation
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public class AnnotationConfigurationException extends RuntimeException {
|
||||
|
||||
Reference in New Issue
Block a user