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 @interface ContextConfiguration { 106 * 107 * @AliasFor("locations") 108 * String[] value() default {}; 109 * 110 * @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"> @ContextConfiguration 123 * public @interface XmlTestConfig { 124 * 125 * @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"> @ContextConfiguration 136 * public @interface MyTestConfig { 137 * 138 * @AliasFor(annotation = ContextConfiguration.class, attribute = "locations") 139 * String[] value() default {}; 140 * 141 * @AliasFor(annotation = ContextConfiguration.class, attribute = "locations") 142 * String[] groovyScripts() default {}; 143 * 144 * @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"> @MyTestConfig 158 * public @interface GroovyOrXmlTestConfig { 159 * 160 * @AliasFor(annotation = MyTestConfig.class, attribute = "groovyScripts") 161 * String[] groovy() default {}; 162 * 163 * @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 — 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}