001/*
002 * Copyright 2002-2015 the original author or authors.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *      https://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package org.springframework.core.annotation;
018
019import java.lang.annotation.Annotation;
020import java.lang.annotation.Documented;
021import java.lang.annotation.ElementType;
022import java.lang.annotation.Retention;
023import java.lang.annotation.RetentionPolicy;
024import java.lang.annotation.Target;
025
026/**
027 * {@code @AliasFor} is an annotation that is used to declare aliases for
028 * annotation attributes.
029 *
030 * <h3>Usage Scenarios</h3>
031 * <ul>
032 * <li><strong>Explicit aliases within an annotation</strong>: within a single
033 * annotation, {@code @AliasFor} can be declared on a pair of attributes to
034 * signal that they are interchangeable aliases for each other.</li>
035 * <li><strong>Explicit alias for attribute in meta-annotation</strong>: if the
036 * {@link #annotation} attribute of {@code @AliasFor} is set to a different
037 * annotation than the one that declares it, the {@link #attribute} is
038 * interpreted as an alias for an attribute in a meta-annotation (i.e., an
039 * explicit meta-annotation attribute override). This enables fine-grained
040 * control over exactly which attributes are overridden within an annotation
041 * hierarchy. In fact, with {@code @AliasFor} it is even possible to declare
042 * an alias for the {@code value} attribute of a meta-annotation.</li>
043 * <li><strong>Implicit aliases within an annotation</strong>: if one or
044 * more attributes within an annotation are declared as attribute overrides
045 * for the same meta-annotation attribute (either directly or transitively),
046 * those attributes will be treated as a set of <em>implicit</em> aliases
047 * for each other, resulting in behavior analogous to that for explicit
048 * aliases within an annotation.</li>
049 * </ul>
050 *
051 * <h3>Usage Requirements</h3>
052 * <p>Like with any annotation in Java, the mere presence of {@code @AliasFor}
053 * on its own will not enforce alias semantics. For alias semantics to be
054 * enforced, annotations must be <em>loaded</em> via {@link MergedAnnotations}.
055 *
056 * <h3>Implementation Requirements</h3>
057 * <ul>
058 * <li><strong>Explicit aliases within an annotation</strong>:
059 * <ol>
060 * <li>Each attribute that makes up an aliased pair should be annotated with
061 * {@code @AliasFor}, and either {@link #attribute} or {@link #value} must
062 * reference the <em>other</em> attribute in the pair. Since Spring Framework
063 * 5.2.1 it is technically possible to annotate only one of the attributes in an
064 * aliased pair; however, it is recommended to annotate both attributes in an
065 * aliased pair for better documentation as well as compatibility with previous
066 * versions of the Spring Framework.</li>
067 * <li>Aliased attributes must declare the same return type.</li>
068 * <li>Aliased attributes must declare a default value.</li>
069 * <li>Aliased attributes must declare the same default value.</li>
070 * <li>{@link #annotation} should not be declared.</li>
071 * </ol>
072 * </li>
073 * <li><strong>Explicit alias for attribute in meta-annotation</strong>:
074 * <ol>
075 * <li>The attribute that is an alias for an attribute in a meta-annotation
076 * must be annotated with {@code @AliasFor}, and {@link #attribute} must
077 * reference the attribute in the meta-annotation.</li>
078 * <li>Aliased attributes must declare the same return type.</li>
079 * <li>{@link #annotation} must reference the meta-annotation.</li>
080 * <li>The referenced meta-annotation must be <em>meta-present</em> on the
081 * annotation class that declares {@code @AliasFor}.</li>
082 * </ol>
083 * </li>
084 * <li><strong>Implicit aliases within an annotation</strong>:
085 * <ol>
086 * <li>Each attribute that belongs to a set of implicit aliases must be
087 * annotated with {@code @AliasFor}, and {@link #attribute} must reference
088 * the same attribute in the same meta-annotation (either directly or
089 * transitively via other explicit meta-annotation attribute overrides
090 * within the annotation hierarchy).</li>
091 * <li>Aliased attributes must declare the same return type.</li>
092 * <li>Aliased attributes must declare a default value.</li>
093 * <li>Aliased attributes must declare the same default value.</li>
094 * <li>{@link #annotation} must reference an appropriate meta-annotation.</li>
095 * <li>The referenced meta-annotation must be <em>meta-present</em> on the
096 * annotation class that declares {@code @AliasFor}.</li>
097 * </ol>
098 * </li>
099 * </ul>
100 *
101 * <h3>Example: Explicit Aliases within an Annotation</h3>
102 * <p>In {@code @ContextConfiguration}, {@code value} and {@code locations}
103 * are explicit aliases for each other.
104 *
105 * <pre class="code"> public &#064;interface ContextConfiguration {
106 *
107 *    &#064;AliasFor("locations")
108 *    String[] value() default {};
109 *
110 *    &#064;AliasFor("value")
111 *    String[] locations() default {};
112 *
113 *    // ...
114 * }</pre>
115 *
116 * <h3>Example: Explicit Alias for Attribute in Meta-annotation</h3>
117 * <p>In {@code @XmlTestConfig}, {@code xmlFiles} is an explicit alias for
118 * {@code locations} in {@code @ContextConfiguration}. In other words,
119 * {@code xmlFiles} overrides the {@code locations} attribute in
120 * {@code @ContextConfiguration}.
121 *
122 * <pre class="code"> &#064;ContextConfiguration
123 * public &#064;interface XmlTestConfig {
124 *
125 *    &#064;AliasFor(annotation = ContextConfiguration.class, attribute = "locations")
126 *    String[] xmlFiles();
127 * }</pre>
128 *
129 * <h3>Example: Implicit Aliases within an Annotation</h3>
130 * <p>In {@code @MyTestConfig}, {@code value}, {@code groovyScripts}, and
131 * {@code xmlFiles} are all explicit meta-annotation attribute overrides for
132 * the {@code locations} attribute in {@code @ContextConfiguration}. These
133 * three attributes are therefore also implicit aliases for each other.
134 *
135 * <pre class="code"> &#064;ContextConfiguration
136 * public &#064;interface MyTestConfig {
137 *
138 *    &#064;AliasFor(annotation = ContextConfiguration.class, attribute = "locations")
139 *    String[] value() default {};
140 *
141 *    &#064;AliasFor(annotation = ContextConfiguration.class, attribute = "locations")
142 *    String[] groovyScripts() default {};
143 *
144 *    &#064;AliasFor(annotation = ContextConfiguration.class, attribute = "locations")
145 *    String[] xmlFiles() default {};
146 * }</pre>
147 *
148 * <h3>Example: Transitive Implicit Aliases within an Annotation</h3>
149 * <p>In {@code @GroovyOrXmlTestConfig}, {@code groovy} is an explicit
150 * override for the {@code groovyScripts} attribute in {@code @MyTestConfig};
151 * whereas, {@code xml} is an explicit override for the {@code locations}
152 * attribute in {@code @ContextConfiguration}. Furthermore, {@code groovy}
153 * and {@code xml} are transitive implicit aliases for each other, since they
154 * both effectively override the {@code locations} attribute in
155 * {@code @ContextConfiguration}.
156 *
157 * <pre class="code"> &#064;MyTestConfig
158 * public &#064;interface GroovyOrXmlTestConfig {
159 *
160 *    &#064;AliasFor(annotation = MyTestConfig.class, attribute = "groovyScripts")
161 *    String[] groovy() default {};
162 *
163 *    &#064;AliasFor(annotation = ContextConfiguration.class, attribute = "locations")
164 *    String[] xml() default {};
165 * }</pre>
166 *
167 * <h3>Spring Annotations Supporting Attribute Aliases</h3>
168 * <p>As of Spring Framework 4.2, several annotations within core Spring
169 * have been updated to use {@code @AliasFor} to configure their internal
170 * attribute aliases. Consult the Javadoc for individual annotations as well
171 * as the reference manual for details.
172 *
173 * @author Sam Brannen
174 * @since 4.2
175 * @see MergedAnnotations
176 * @see SynthesizedAnnotation
177 */
178@Retention(RetentionPolicy.RUNTIME)
179@Target(ElementType.METHOD)
180@Documented
181public @interface AliasFor {
182
183        /**
184         * Alias for {@link #attribute}.
185         * <p>Intended to be used instead of {@link #attribute} when {@link #annotation}
186         * is not declared &mdash; for example: {@code @AliasFor("value")} instead of
187         * {@code @AliasFor(attribute = "value")}.
188         */
189        @AliasFor("attribute")
190        String value() default "";
191
192        /**
193         * The name of the attribute that <em>this</em> attribute is an alias for.
194         * @see #value
195         */
196        @AliasFor("value")
197        String attribute() default "";
198
199        /**
200         * The type of annotation in which the aliased {@link #attribute} is declared.
201         * <p>Defaults to {@link Annotation}, implying that the aliased attribute is
202         * declared in the same annotation as <em>this</em> attribute.
203         */
204        Class<? extends Annotation> annotation() default Annotation.class;
205
206}