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 the utility methods in 055 * {@link AnnotationUtils}. Behind the scenes, Spring will <em>synthesize</em> 056 * an annotation by wrapping it in a dynamic proxy that transparently enforces 057 * <em>attribute alias</em> semantics for annotation attributes that are 058 * annotated with {@code @AliasFor}. Similarly, {@link AnnotatedElementUtils} 059 * supports explicit meta-annotation attribute overrides when {@code @AliasFor} 060 * is used within an annotation hierarchy. Typically you will not need to 061 * manually synthesize annotations on your own since Spring will do that for 062 * you transparently when looking up annotations on Spring-managed components. 063 * 064 * <h3>Implementation Requirements</h3> 065 * <ul> 066 * <li><strong>Explicit aliases within an annotation</strong>: 067 * <ol> 068 * <li>Each attribute that makes up an aliased pair must be annotated with 069 * {@code @AliasFor}, and either {@link #attribute} or {@link #value} must 070 * reference the <em>other</em> attribute in the pair.</li> 071 * <li>Aliased attributes must declare the same return type.</li> 072 * <li>Aliased attributes must declare a default value.</li> 073 * <li>Aliased attributes must declare the same default value.</li> 074 * <li>{@link #annotation} should not be declared.</li> 075 * </ol> 076 * </li> 077 * <li><strong>Explicit alias for attribute in meta-annotation</strong>: 078 * <ol> 079 * <li>The attribute that is an alias for an attribute in a meta-annotation 080 * must be annotated with {@code @AliasFor}, and {@link #attribute} must 081 * reference the attribute in the meta-annotation.</li> 082 * <li>Aliased attributes must declare the same return type.</li> 083 * <li>{@link #annotation} must reference the meta-annotation.</li> 084 * <li>The referenced meta-annotation must be <em>meta-present</em> on the 085 * annotation class that declares {@code @AliasFor}.</li> 086 * </ol> 087 * </li> 088 * <li><strong>Implicit aliases within an annotation</strong>: 089 * <ol> 090 * <li>Each attribute that belongs to a set of implicit aliases must be 091 * annotated with {@code @AliasFor}, and {@link #attribute} must reference 092 * the same attribute in the same meta-annotation (either directly or 093 * transitively via other explicit meta-annotation attribute overrides 094 * within the annotation hierarchy).</li> 095 * <li>Aliased attributes must declare the same return type.</li> 096 * <li>Aliased attributes must declare a default value.</li> 097 * <li>Aliased attributes must declare the same default value.</li> 098 * <li>{@link #annotation} must reference an appropriate meta-annotation.</li> 099 * <li>The referenced meta-annotation must be <em>meta-present</em> on the 100 * annotation class that declares {@code @AliasFor}.</li> 101 * </ol> 102 * </li> 103 * </ul> 104 * 105 * <h3>Example: Explicit Aliases within an Annotation</h3> 106 * <p>In {@code @ContextConfiguration}, {@code value} and {@code locations} 107 * are explicit aliases for each other. 108 * 109 * <pre class="code"> public @interface ContextConfiguration { 110 * 111 * @AliasFor("locations") 112 * String[] value() default {}; 113 * 114 * @AliasFor("value") 115 * String[] locations() default {}; 116 * 117 * // ... 118 * }</pre> 119 * 120 * <h3>Example: Explicit Alias for Attribute in Meta-annotation</h3> 121 * <p>In {@code @XmlTestConfig}, {@code xmlFiles} is an explicit alias for 122 * {@code locations} in {@code @ContextConfiguration}. In other words, 123 * {@code xmlFiles} overrides the {@code locations} attribute in 124 * {@code @ContextConfiguration}. 125 * 126 * <pre class="code"> @ContextConfiguration 127 * public @interface XmlTestConfig { 128 * 129 * @AliasFor(annotation = ContextConfiguration.class, attribute = "locations") 130 * String[] xmlFiles(); 131 * }</pre> 132 * 133 * <h3>Example: Implicit Aliases within an Annotation</h3> 134 * <p>In {@code @MyTestConfig}, {@code value}, {@code groovyScripts}, and 135 * {@code xmlFiles} are all explicit meta-annotation attribute overrides for 136 * the {@code locations} attribute in {@code @ContextConfiguration}. These 137 * three attributes are therefore also implicit aliases for each other. 138 * 139 * <pre class="code"> @ContextConfiguration 140 * public @interface MyTestConfig { 141 * 142 * @AliasFor(annotation = ContextConfiguration.class, attribute = "locations") 143 * String[] value() default {}; 144 * 145 * @AliasFor(annotation = ContextConfiguration.class, attribute = "locations") 146 * String[] groovyScripts() default {}; 147 * 148 * @AliasFor(annotation = ContextConfiguration.class, attribute = "locations") 149 * String[] xmlFiles() default {}; 150 * }</pre> 151 * 152 * <h3>Example: Transitive Implicit Aliases within an Annotation</h3> 153 * <p>In {@code @GroovyOrXmlTestConfig}, {@code groovy} is an explicit 154 * override for the {@code groovyScripts} attribute in {@code @MyTestConfig}; 155 * whereas, {@code xml} is an explicit override for the {@code locations} 156 * attribute in {@code @ContextConfiguration}. Furthermore, {@code groovy} 157 * and {@code xml} are transitive implicit aliases for each other, since they 158 * both effectively override the {@code locations} attribute in 159 * {@code @ContextConfiguration}. 160 * 161 * <pre class="code"> @MyTestConfig 162 * public @interface GroovyOrXmlTestConfig { 163 * 164 * @AliasFor(annotation = MyTestConfig.class, attribute = "groovyScripts") 165 * String[] groovy() default {}; 166 * 167 * @AliasFor(annotation = ContextConfiguration.class, attribute = "locations") 168 * String[] xml() default {}; 169 * }</pre> 170 * 171 * <h3>Spring Annotations Supporting Attribute Aliases</h3> 172 * <p>As of Spring Framework 4.2, several annotations within core Spring 173 * have been updated to use {@code @AliasFor} to configure their internal 174 * attribute aliases. Consult the Javadoc for individual annotations as well 175 * as the reference manual for details. 176 * 177 * @author Sam Brannen 178 * @since 4.2 179 * @see AnnotatedElementUtils 180 * @see AnnotationUtils 181 * @see AnnotationUtils#synthesizeAnnotation(Annotation, java.lang.reflect.AnnotatedElement) 182 * @see SynthesizedAnnotation 183 */ 184@Retention(RetentionPolicy.RUNTIME) 185@Target(ElementType.METHOD) 186@Documented 187public @interface AliasFor { 188 189 /** 190 * Alias for {@link #attribute}. 191 * <p>Intended to be used instead of {@link #attribute} when {@link #annotation} 192 * is not declared — for example: {@code @AliasFor("value")} instead of 193 * {@code @AliasFor(attribute = "value")}. 194 */ 195 @AliasFor("attribute") 196 String value() default ""; 197 198 /** 199 * The name of the attribute that <em>this</em> attribute is an alias for. 200 * @see #value 201 */ 202 @AliasFor("value") 203 String attribute() default ""; 204 205 /** 206 * The type of annotation in which the aliased {@link #attribute} is declared. 207 * <p>Defaults to {@link Annotation}, implying that the aliased attribute is 208 * declared in the same annotation as <em>this</em> attribute. 209 */ 210 Class<? extends Annotation> annotation() default Annotation.class; 211 212}