AnnotationMetadataTests.java 25.0 KB
Newer Older
A
Arjen Poutsma 已提交
1
/*
J
Juergen Hoeller 已提交
2
 * Copyright 2002-2019 the original author or authors.
A
Arjen Poutsma 已提交
3 4 5 6 7
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
S
Spring Operator 已提交
8
 *      https://www.apache.org/licenses/LICENSE-2.0
A
Arjen Poutsma 已提交
9 10 11 12 13 14 15 16 17 18 19
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.core.type;

import java.io.Serializable;
20
import java.lang.annotation.Annotation;
21
import java.lang.annotation.Documented;
22
import java.lang.annotation.ElementType;
23
import java.lang.annotation.Inherited;
24 25 26
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
27 28 29
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
30
import java.util.Set;
A
Arjen Poutsma 已提交
31

32
import org.junit.Test;
33

34
import org.springframework.core.annotation.AliasFor;
35
import org.springframework.core.annotation.AnnotationAttributes;
A
Arjen Poutsma 已提交
36
import org.springframework.core.type.classreading.MetadataReader;
37
import org.springframework.core.type.classreading.MetadataReaderFactory;
A
Arjen Poutsma 已提交
38 39 40
import org.springframework.core.type.classreading.SimpleMetadataReaderFactory;
import org.springframework.stereotype.Component;

41
import static org.hamcrest.CoreMatchers.*;
42
import static org.hamcrest.MatcherAssert.assertThat;
43 44
import static org.junit.Assert.*;

A
Arjen Poutsma 已提交
45
/**
46 47 48
 * Unit tests demonstrating that the reflection-based {@link StandardAnnotationMetadata}
 * and ASM-based {@code AnnotationMetadataReadingVisitor} produce identical output.
 *
A
Arjen Poutsma 已提交
49
 * @author Juergen Hoeller
50
 * @author Chris Beams
51
 * @author Phillip Webb
52
 * @author Sam Brannen
A
Arjen Poutsma 已提交
53
 */
54
public class AnnotationMetadataTests {
A
Arjen Poutsma 已提交
55

56
	@Test
57
	public void standardAnnotationMetadata() {
58 59 60
		AnnotationMetadata metadata = new StandardAnnotationMetadata(AnnotatedComponent.class, true);
		doTestAnnotationInfo(metadata);
		doTestMethodAnnotationInfo(metadata);
A
Arjen Poutsma 已提交
61 62
	}

63
	@Test
64
	public void asmAnnotationMetadata() throws Exception {
A
Arjen Poutsma 已提交
65 66
		MetadataReaderFactory metadataReaderFactory = new SimpleMetadataReaderFactory();
		MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(AnnotatedComponent.class.getName());
67 68 69 70 71
		AnnotationMetadata metadata = metadataReader.getAnnotationMetadata();
		doTestAnnotationInfo(metadata);
		doTestMethodAnnotationInfo(metadata);
	}

72
	@Test
73
	public void standardAnnotationMetadataForSubclass() {
74 75 76 77 78 79 80 81 82 83 84 85
		AnnotationMetadata metadata = new StandardAnnotationMetadata(AnnotatedComponentSubClass.class, true);
		doTestSubClassAnnotationInfo(metadata);
	}

	@Test
	public void asmAnnotationMetadataForSubclass() throws Exception {
		MetadataReaderFactory metadataReaderFactory = new SimpleMetadataReaderFactory();
		MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(AnnotatedComponentSubClass.class.getName());
		AnnotationMetadata metadata = metadataReader.getAnnotationMetadata();
		doTestSubClassAnnotationInfo(metadata);
	}

86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
	private void doTestSubClassAnnotationInfo(AnnotationMetadata metadata) {
		assertThat(metadata.getClassName(), is(AnnotatedComponentSubClass.class.getName()));
		assertThat(metadata.isInterface(), is(false));
		assertThat(metadata.isAnnotation(), is(false));
		assertThat(metadata.isAbstract(), is(false));
		assertThat(metadata.isConcrete(), is(true));
		assertThat(metadata.hasSuperClass(), is(true));
		assertThat(metadata.getSuperClassName(), is(AnnotatedComponent.class.getName()));
		assertThat(metadata.getInterfaceNames().length, is(0));
		assertThat(metadata.isAnnotated(Component.class.getName()), is(false));
		assertThat(metadata.isAnnotated(Scope.class.getName()), is(false));
		assertThat(metadata.isAnnotated(SpecialAttr.class.getName()), is(false));
		assertThat(metadata.hasAnnotation(Component.class.getName()), is(false));
		assertThat(metadata.hasAnnotation(Scope.class.getName()), is(false));
		assertThat(metadata.hasAnnotation(SpecialAttr.class.getName()), is(false));
		assertThat(metadata.getAnnotationTypes().size(), is(0));
		assertThat(metadata.getAnnotationAttributes(Component.class.getName()), nullValue());
		assertThat(metadata.getAnnotatedMethods(DirectAnnotation.class.getName()).size(), equalTo(0));
		assertThat(metadata.isAnnotated(IsAnnotatedAnnotation.class.getName()), equalTo(false));
		assertThat(metadata.getAllAnnotationAttributes(DirectAnnotation.class.getName()), nullValue());
	}

	@Test
109
	public void standardAnnotationMetadataForInterface() {
110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
		AnnotationMetadata metadata = new StandardAnnotationMetadata(AnnotationMetadata.class, true);
		doTestMetadataForInterfaceClass(metadata);
	}

	@Test
	public void asmAnnotationMetadataForInterface() throws Exception {
		MetadataReaderFactory metadataReaderFactory = new SimpleMetadataReaderFactory();
		MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(AnnotationMetadata.class.getName());
		AnnotationMetadata metadata = metadataReader.getAnnotationMetadata();
		doTestMetadataForInterfaceClass(metadata);
	}

	private void doTestMetadataForInterfaceClass(AnnotationMetadata metadata) {
		assertThat(metadata.getClassName(), is(AnnotationMetadata.class.getName()));
		assertThat(metadata.isInterface(), is(true));
		assertThat(metadata.isAnnotation(), is(false));
		assertThat(metadata.isAbstract(), is(true));
		assertThat(metadata.isConcrete(), is(false));
		assertThat(metadata.hasSuperClass(), is(false));
		assertThat(metadata.getSuperClassName(), nullValue());
		assertThat(metadata.getInterfaceNames().length, is(2));
		assertThat(metadata.getInterfaceNames()[0], is(ClassMetadata.class.getName()));
		assertThat(metadata.getInterfaceNames()[1], is(AnnotatedTypeMetadata.class.getName()));
		assertThat(metadata.getAnnotationTypes().size(), is(0));
	}

	@Test
137
	public void standardAnnotationMetadataForAnnotation() {
138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
		AnnotationMetadata metadata = new StandardAnnotationMetadata(Component.class, true);
		doTestMetadataForAnnotationClass(metadata);
	}

	@Test
	public void asmAnnotationMetadataForAnnotation() throws Exception {
		MetadataReaderFactory metadataReaderFactory = new SimpleMetadataReaderFactory();
		MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(Component.class.getName());
		AnnotationMetadata metadata = metadataReader.getAnnotationMetadata();
		doTestMetadataForAnnotationClass(metadata);
	}

	private void doTestMetadataForAnnotationClass(AnnotationMetadata metadata) {
		assertThat(metadata.getClassName(), is(Component.class.getName()));
		assertThat(metadata.isInterface(), is(true));
		assertThat(metadata.isAnnotation(), is(true));
		assertThat(metadata.isAbstract(), is(true));
		assertThat(metadata.isConcrete(), is(false));
		assertThat(metadata.hasSuperClass(), is(false));
		assertThat(metadata.getSuperClassName(), nullValue());
		assertThat(metadata.getInterfaceNames().length, is(1));
		assertThat(metadata.getInterfaceNames()[0], is(Annotation.class.getName()));
160
		assertThat(metadata.isAnnotated(Documented.class.getName()), is(false));
161 162
		assertThat(metadata.isAnnotated(Scope.class.getName()), is(false));
		assertThat(metadata.isAnnotated(SpecialAttr.class.getName()), is(false));
163
		assertThat(metadata.hasAnnotation(Documented.class.getName()), is(false));
164 165
		assertThat(metadata.hasAnnotation(Scope.class.getName()), is(false));
		assertThat(metadata.hasAnnotation(SpecialAttr.class.getName()), is(false));
166
		assertThat(metadata.getAnnotationTypes().size(), is(1));
167 168
	}

169 170 171 172 173 174 175 176
	/**
	 * In order to preserve backward-compatibility, {@link StandardAnnotationMetadata}
	 * defaults to return nested annotations and annotation arrays as actual
	 * Annotation instances. It is recommended for compatibility with ASM-based
	 * AnnotationMetadata implementations to set the 'nestedAnnotationsAsMap' flag to
	 * 'true' as is done in the main test above.
	 */
	@Test
177
	public void standardAnnotationMetadata_nestedAnnotationsAsMap_false() {
178 179
		AnnotationMetadata metadata = new StandardAnnotationMetadata(AnnotatedComponent.class);
		AnnotationAttributes specialAttrs = (AnnotationAttributes) metadata.getAnnotationAttributes(SpecialAttr.class.getName());
180
		Annotation[] nestedAnnoArray = (Annotation[]) specialAttrs.get("nestedAnnoArray");
181
		assertThat(nestedAnnoArray[0], instanceOf(NestedAnno.class));
A
Arjen Poutsma 已提交
182 183
	}

184 185
	@Test
	public void metaAnnotationOverridesUsingStandardAnnotationMetadata() {
186
		AnnotationMetadata metadata = new StandardAnnotationMetadata(ComposedConfigurationWithAttributeOverridesClass.class);
187 188 189 190 191 192 193 194 195 196 197 198 199
		assertMetaAnnotationOverrides(metadata);
	}

	@Test
	public void metaAnnotationOverridesUsingAnnotationMetadataReadingVisitor() throws Exception {
		MetadataReaderFactory metadataReaderFactory = new SimpleMetadataReaderFactory();
		MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(ComposedConfigurationWithAttributeOverridesClass.class.getName());
		AnnotationMetadata metadata = metadataReader.getAnnotationMetadata();
		assertMetaAnnotationOverrides(metadata);
	}

	private void assertMetaAnnotationOverrides(AnnotationMetadata metadata) {
		AnnotationAttributes attributes = (AnnotationAttributes) metadata.getAnnotationAttributes(
J
Juergen Hoeller 已提交
200
				TestComponentScan.class.getName(), false);
201 202 203 204 205 206 207 208 209
		String[] basePackages = attributes.getStringArray("basePackages");
		assertThat("length of basePackages[]", basePackages.length, is(1));
		assertThat("basePackages[0]", basePackages[0], is("org.example.componentscan"));
		String[] value = attributes.getStringArray("value");
		assertThat("length of value[]", value.length, is(0));
		Class<?>[] basePackageClasses = attributes.getClassArray("basePackageClasses");
		assertThat("length of basePackageClasses[]", basePackageClasses.length, is(0));
	}

J
Juergen Hoeller 已提交
210
	@Test  // SPR-11649
211 212 213 214
	public void multipleAnnotationsWithIdenticalAttributeNamesUsingStandardAnnotationMetadata() {
		AnnotationMetadata metadata = new StandardAnnotationMetadata(NamedAnnotationsClass.class);
		assertMultipleAnnotationsWithIdenticalAttributeNames(metadata);
	}
215

J
Juergen Hoeller 已提交
216
	@Test  // SPR-11649
217 218 219 220 221 222
	public void multipleAnnotationsWithIdenticalAttributeNamesUsingAnnotationMetadataReadingVisitor() throws Exception {
		MetadataReaderFactory metadataReaderFactory = new SimpleMetadataReaderFactory();
		MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(NamedAnnotationsClass.class.getName());
		AnnotationMetadata metadata = metadataReader.getAnnotationMetadata();
		assertMultipleAnnotationsWithIdenticalAttributeNames(metadata);
	}
223

J
Juergen Hoeller 已提交
224
	@Test  // SPR-11649
225 226 227 228
	public void composedAnnotationWithMetaAnnotationsWithIdenticalAttributeNamesUsingStandardAnnotationMetadata() {
		AnnotationMetadata metadata = new StandardAnnotationMetadata(NamedComposedAnnotationClass.class);
		assertMultipleAnnotationsWithIdenticalAttributeNames(metadata);
	}
229

J
Juergen Hoeller 已提交
230
	@Test  // SPR-11649
231 232 233 234 235 236 237
	public void composedAnnotationWithMetaAnnotationsWithIdenticalAttributeNamesUsingAnnotationMetadataReadingVisitor() throws Exception {
		MetadataReaderFactory metadataReaderFactory = new SimpleMetadataReaderFactory();
		MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(NamedComposedAnnotationClass.class.getName());
		AnnotationMetadata metadata = metadataReader.getAnnotationMetadata();
		assertMultipleAnnotationsWithIdenticalAttributeNames(metadata);
	}

238 239 240 241 242 243 244 245 246 247 248 249 250 251
	@Test
	public void inheritedAnnotationWithMetaAnnotationsWithIdenticalAttributeNamesUsingStandardAnnotationMetadata() {
		AnnotationMetadata metadata = new StandardAnnotationMetadata(NamedComposedAnnotationExtended.class);
		assertFalse(metadata.hasAnnotation(NamedComposedAnnotation.class.getName()));
	}

	@Test
	public void inheritedAnnotationWithMetaAnnotationsWithIdenticalAttributeNamesUsingAnnotationMetadataReadingVisitor() throws Exception {
		MetadataReaderFactory metadataReaderFactory = new SimpleMetadataReaderFactory();
		MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(NamedComposedAnnotationExtended.class.getName());
		AnnotationMetadata metadata = metadataReader.getAnnotationMetadata();
		assertFalse(metadata.hasAnnotation(NamedComposedAnnotation.class.getName()));
	}

252

253 254 255 256 257 258 259 260 261 262 263 264 265 266 267
	private void assertMultipleAnnotationsWithIdenticalAttributeNames(AnnotationMetadata metadata) {
		AnnotationAttributes attributes1 = (AnnotationAttributes) metadata.getAnnotationAttributes(
				NamedAnnotation1.class.getName(), false);
		String name1 = attributes1.getString("name");
		assertThat("name of NamedAnnotation1", name1, is("name 1"));

		AnnotationAttributes attributes2 = (AnnotationAttributes) metadata.getAnnotationAttributes(
				NamedAnnotation2.class.getName(), false);
		String name2 = attributes2.getString("name");
		assertThat("name of NamedAnnotation2", name2, is("name 2"));

		AnnotationAttributes attributes3 = (AnnotationAttributes) metadata.getAnnotationAttributes(
				NamedAnnotation3.class.getName(), false);
		String name3 = attributes3.getString("name");
		assertThat("name of NamedAnnotation3", name3, is("name 3"));
268 269
	}

A
Arjen Poutsma 已提交
270
	private void doTestAnnotationInfo(AnnotationMetadata metadata) {
271 272
		assertThat(metadata.getClassName(), is(AnnotatedComponent.class.getName()));
		assertThat(metadata.isInterface(), is(false));
273
		assertThat(metadata.isAnnotation(), is(false));
274 275 276 277 278 279 280 281 282 283
		assertThat(metadata.isAbstract(), is(false));
		assertThat(metadata.isConcrete(), is(true));
		assertThat(metadata.hasSuperClass(), is(true));
		assertThat(metadata.getSuperClassName(), is(Object.class.getName()));
		assertThat(metadata.getInterfaceNames().length, is(1));
		assertThat(metadata.getInterfaceNames()[0], is(Serializable.class.getName()));

		assertThat(metadata.hasAnnotation(Component.class.getName()), is(true));
		assertThat(metadata.hasAnnotation(Scope.class.getName()), is(true));
		assertThat(metadata.hasAnnotation(SpecialAttr.class.getName()), is(true));
284
		assertThat(metadata.getAnnotationTypes().size(), is(6));
285 286 287 288 289 290 291 292 293 294
		assertThat(metadata.getAnnotationTypes().contains(Component.class.getName()), is(true));
		assertThat(metadata.getAnnotationTypes().contains(Scope.class.getName()), is(true));
		assertThat(metadata.getAnnotationTypes().contains(SpecialAttr.class.getName()), is(true));

		AnnotationAttributes compAttrs = (AnnotationAttributes) metadata.getAnnotationAttributes(Component.class.getName());
		assertThat(compAttrs.size(), is(1));
		assertThat(compAttrs.getString("value"), is("myName"));
		AnnotationAttributes scopeAttrs = (AnnotationAttributes) metadata.getAnnotationAttributes(Scope.class.getName());
		assertThat(scopeAttrs.size(), is(1));
		assertThat(scopeAttrs.getString("value"), is("myScope"));
295 296 297 298

		Set<MethodMetadata> methods = metadata.getAnnotatedMethods(DirectAnnotation.class.getName());
		MethodMetadata method = methods.iterator().next();
		assertEquals("direct", method.getAnnotationAttributes(DirectAnnotation.class.getName()).get("value"));
299
		assertEquals("direct", method.getAnnotationAttributes(DirectAnnotation.class.getName()).get("myValue"));
300
		List<Object> allMeta = method.getAllAnnotationAttributes(DirectAnnotation.class.getName()).get("value");
301
		assertThat(new HashSet<>(allMeta), is(equalTo(new HashSet<Object>(Arrays.asList("direct", "meta")))));
302
		allMeta = method.getAllAnnotationAttributes(DirectAnnotation.class.getName()).get("additional");
303
		assertThat(new HashSet<>(allMeta), is(equalTo(new HashSet<Object>(Arrays.asList("direct")))));
304 305 306

		assertTrue(metadata.isAnnotated(IsAnnotatedAnnotation.class.getName()));

307 308 309
		{ // perform tests with classValuesAsString = false (the default)
			AnnotationAttributes specialAttrs = (AnnotationAttributes) metadata.getAnnotationAttributes(SpecialAttr.class.getName());
			assertThat(specialAttrs.size(), is(6));
310 311
			assertTrue(String.class.isAssignableFrom(specialAttrs.getClass("clazz")));
			assertTrue(specialAttrs.getEnum("state").equals(Thread.State.NEW));
312 313 314

			AnnotationAttributes nestedAnno = specialAttrs.getAnnotation("nestedAnno");
			assertThat("na", is(nestedAnno.getString("value")));
315
			assertTrue(nestedAnno.getEnum("anEnum").equals(SomeEnum.LABEL1));
316
			assertArrayEquals(new Class<?>[] {String.class}, (Class<?>[]) nestedAnno.get("classArray"));
317 318 319 320

			AnnotationAttributes[] nestedAnnoArray = specialAttrs.getAnnotationArray("nestedAnnoArray");
			assertThat(nestedAnnoArray.length, is(2));
			assertThat(nestedAnnoArray[0].getString("value"), is("default"));
321
			assertTrue(nestedAnnoArray[0].getEnum("anEnum").equals(SomeEnum.DEFAULT));
322
			assertArrayEquals(new Class<?>[] {Void.class}, (Class<?>[]) nestedAnnoArray[0].get("classArray"));
323
			assertThat(nestedAnnoArray[1].getString("value"), is("na1"));
324
			assertTrue(nestedAnnoArray[1].getEnum("anEnum").equals(SomeEnum.LABEL2));
325 326
			assertArrayEquals(new Class<?>[] {Number.class}, (Class<?>[]) nestedAnnoArray[1].get("classArray"));
			assertArrayEquals(new Class<?>[] {Number.class}, nestedAnnoArray[1].getClassArray("classArray"));
327 328 329

			AnnotationAttributes optional = specialAttrs.getAnnotation("optional");
			assertThat(optional.getString("value"), is("optional"));
330
			assertTrue(optional.getEnum("anEnum").equals(SomeEnum.DEFAULT));
331 332
			assertArrayEquals(new Class<?>[] {Void.class}, (Class<?>[]) optional.get("classArray"));
			assertArrayEquals(new Class<?>[] {Void.class}, optional.getClassArray("classArray"));
333 334 335 336

			AnnotationAttributes[] optionalArray = specialAttrs.getAnnotationArray("optionalArray");
			assertThat(optionalArray.length, is(1));
			assertThat(optionalArray[0].getString("value"), is("optional"));
337
			assertTrue(optionalArray[0].getEnum("anEnum").equals(SomeEnum.DEFAULT));
338 339
			assertArrayEquals(new Class<?>[] {Void.class}, (Class<?>[]) optionalArray[0].get("classArray"));
			assertArrayEquals(new Class<?>[] {Void.class}, optionalArray[0].getClassArray("classArray"));
340 341 342

			assertEquals("direct", metadata.getAnnotationAttributes(DirectAnnotation.class.getName()).get("value"));
			allMeta = metadata.getAllAnnotationAttributes(DirectAnnotation.class.getName()).get("value");
343
			assertThat(new HashSet<>(allMeta), is(equalTo(new HashSet<Object>(Arrays.asList("direct", "meta")))));
344
			allMeta = metadata.getAllAnnotationAttributes(DirectAnnotation.class.getName()).get("additional");
345 346 347
			assertThat(new HashSet<>(allMeta), is(equalTo(new HashSet<Object>(Arrays.asList("direct", "")))));
			assertEquals("", metadata.getAnnotationAttributes(DirectAnnotation.class.getName()).get("additional"));
			assertEquals(0, ((String[]) metadata.getAnnotationAttributes(DirectAnnotation.class.getName()).get("additionalArray")).length);
348 349
		}
		{ // perform tests with classValuesAsString = true
350 351
			AnnotationAttributes specialAttrs = (AnnotationAttributes) metadata.getAnnotationAttributes(
				SpecialAttr.class.getName(), true);
352
			assertThat(specialAttrs.size(), is(6));
353
			assertThat(specialAttrs.get("clazz"), is((Object) String.class.getName()));
354 355 356
			assertThat(specialAttrs.getString("clazz"), is(String.class.getName()));

			AnnotationAttributes nestedAnno = specialAttrs.getAnnotation("nestedAnno");
357 358
			assertArrayEquals(new String[] { String.class.getName() }, nestedAnno.getStringArray("classArray"));
			assertArrayEquals(new String[] { String.class.getName() }, nestedAnno.getStringArray("classArray"));
359 360

			AnnotationAttributes[] nestedAnnoArray = specialAttrs.getAnnotationArray("nestedAnnoArray");
361 362 363 364
			assertArrayEquals(new String[] { Void.class.getName() }, (String[]) nestedAnnoArray[0].get("classArray"));
			assertArrayEquals(new String[] { Void.class.getName() }, nestedAnnoArray[0].getStringArray("classArray"));
			assertArrayEquals(new String[] { Number.class.getName() }, (String[]) nestedAnnoArray[1].get("classArray"));
			assertArrayEquals(new String[] { Number.class.getName() }, nestedAnnoArray[1].getStringArray("classArray"));
365 366

			AnnotationAttributes optional = specialAttrs.getAnnotation("optional");
367 368
			assertArrayEquals(new String[] { Void.class.getName() }, (String[]) optional.get("classArray"));
			assertArrayEquals(new String[] { Void.class.getName() }, optional.getStringArray("classArray"));
369 370

			AnnotationAttributes[] optionalArray = specialAttrs.getAnnotationArray("optionalArray");
371 372
			assertArrayEquals(new String[] { Void.class.getName() }, (String[]) optionalArray[0].get("classArray"));
			assertArrayEquals(new String[] { Void.class.getName() }, optionalArray[0].getStringArray("classArray"));
373

374
			assertEquals("direct", metadata.getAnnotationAttributes(DirectAnnotation.class.getName()).get("value"));
375
			allMeta = metadata.getAllAnnotationAttributes(DirectAnnotation.class.getName()).get("value");
376
			assertThat(new HashSet<>(allMeta), is(equalTo(new HashSet<Object>(Arrays.asList("direct", "meta")))));
377
		}
378
	}
J
Juergen Hoeller 已提交
379

380
	private void doTestMethodAnnotationInfo(AnnotationMetadata classMetadata) {
381
		Set<MethodMetadata> methods = classMetadata.getAnnotatedMethods(TestAutowired.class.getName());
382
		assertThat(methods.size(), is(1));
383
		for (MethodMetadata methodMetadata : methods) {
384
			assertThat(methodMetadata.isAnnotated(TestAutowired.class.getName()), is(true));
385 386
		}
	}
387

388 389 390

	// -------------------------------------------------------------------------

391
	public static enum SomeEnum {
392
		LABEL1, LABEL2, DEFAULT
393 394 395 396 397
	}

	@Target({})
	@Retention(RetentionPolicy.RUNTIME)
	public @interface NestedAnno {
398

399
		String value() default "default";
400

401
		SomeEnum anEnum() default SomeEnum.DEFAULT;
402

403 404
		Class<?>[] classArray() default Void.class;
	}
405 406 407 408 409

	@Target(ElementType.TYPE)
	@Retention(RetentionPolicy.RUNTIME)
	public @interface SpecialAttr {

410
		Class<?> clazz();
A
Arjen Poutsma 已提交
411

412
		Thread.State state();
413 414 415 416 417

		NestedAnno nestedAnno();

		NestedAnno[] nestedAnnoArray();

418
		NestedAnno optional() default @NestedAnno(value = "optional", anEnum = SomeEnum.DEFAULT, classArray = Void.class);
419

420
		NestedAnno[] optionalArray() default { @NestedAnno(value = "optional", anEnum = SomeEnum.DEFAULT, classArray = Void.class) };
A
Arjen Poutsma 已提交
421 422
	}

423
	@Target({ElementType.TYPE, ElementType.METHOD})
424 425
	@Retention(RetentionPolicy.RUNTIME)
	public @interface DirectAnnotation {
426

427 428 429 430 431
		@AliasFor("myValue")
		String value() default "";

		@AliasFor("value")
		String myValue() default "";
432 433

		String additional() default "direct";
434 435

		String[] additionalArray() default "direct";
436 437
	}

438
	@Target(ElementType.TYPE)
439 440 441 442 443 444 445 446 447
	@Retention(RetentionPolicy.RUNTIME)
	public @interface IsAnnotatedAnnotation {
	}

	@Target(ElementType.TYPE)
	@Retention(RetentionPolicy.RUNTIME)
	@DirectAnnotation("meta")
	@IsAnnotatedAnnotation
	public @interface MetaAnnotation {
448 449

		String additional() default "meta";
450 451
	}

452
	@Target({ElementType.TYPE, ElementType.METHOD})
453 454 455 456
	@Retention(RetentionPolicy.RUNTIME)
	@MetaAnnotation
	public @interface MetaMetaAnnotation {
	}
A
Arjen Poutsma 已提交
457

458 459 460
	@Target(ElementType.TYPE)
	@Retention(RetentionPolicy.RUNTIME)
	public @interface EnumSubclasses {
461

462 463 464 465
		SubclassEnum[] value();
	}

	// SPR-10914
466
	public enum SubclassEnum {
467
		FOO {
468
		/* Do not delete! This subclassing is intentional. */
469 470
		},
		BAR {
471
		/* Do not delete! This subclassing is intentional. */
472
		}
473 474
	}

A
Arjen Poutsma 已提交
475 476
	@Component("myName")
	@Scope("myScope")
477 478 479 480
	@SpecialAttr(clazz = String.class, state = Thread.State.NEW,
			nestedAnno = @NestedAnno(value = "na", anEnum = SomeEnum.LABEL1, classArray = {String.class}),
			nestedAnnoArray = {@NestedAnno, @NestedAnno(value = "na1", anEnum = SomeEnum.LABEL2, classArray = {Number.class})})
	@SuppressWarnings({"serial", "unused"})
481
	@DirectAnnotation(value = "direct", additional = "", additionalArray = {})
482
	@MetaMetaAnnotation
483
	@EnumSubclasses({SubclassEnum.FOO, SubclassEnum.BAR})
A
Arjen Poutsma 已提交
484
	private static class AnnotatedComponent implements Serializable {
485

486 487
		@TestAutowired
		public void doWork(@TestQualifier("myColor") java.awt.Color color) {
488
		}
J
Juergen Hoeller 已提交
489

490
		public void doSleep() {
491
		}
492 493 494 495 496

		@DirectAnnotation("direct")
		@MetaMetaAnnotation
		public void meta() {
		}
A
Arjen Poutsma 已提交
497 498
	}

499
	@SuppressWarnings("serial")
500 501 502
	private static class AnnotatedComponentSubClass extends AnnotatedComponent {
	}

503 504 505
	@Target(ElementType.TYPE)
	@Retention(RetentionPolicy.RUNTIME)
	@Component
506
	public @interface TestConfiguration {
507 508 509 510 511 512

		String value() default "";
	}

	@Retention(RetentionPolicy.RUNTIME)
	@Target(ElementType.TYPE)
513
	public @interface TestComponentScan {
514 515 516 517 518 519 520 521 522 523 524 525

		String[] value() default {};

		String[] basePackages() default {};

		Class<?>[] basePackageClasses() default {};
	}

	@TestConfiguration
	@TestComponentScan(basePackages = "bogus")
	@Retention(RetentionPolicy.RUNTIME)
	@Target(ElementType.TYPE)
526
	public @interface ComposedConfigurationWithAttributeOverrides {
527 528 529 530 531 532 533 534

		String[] basePackages() default {};
	}

	@ComposedConfigurationWithAttributeOverrides(basePackages = "org.example.componentscan")
	public static class ComposedConfigurationWithAttributeOverridesClass {
	}

535 536
	@Retention(RetentionPolicy.RUNTIME)
	@Target(ElementType.TYPE)
537
	public @interface NamedAnnotation1 {
538 539 540 541 542
		String name() default "";
	}

	@Retention(RetentionPolicy.RUNTIME)
	@Target(ElementType.TYPE)
543
	public @interface NamedAnnotation2 {
544 545 546 547 548
		String name() default "";
	}

	@Retention(RetentionPolicy.RUNTIME)
	@Target(ElementType.TYPE)
549
	public @interface NamedAnnotation3 {
550 551 552 553 554 555 556 557 558 559 560 561 562 563
		String name() default "";
	}

	@NamedAnnotation1(name = "name 1")
	@NamedAnnotation2(name = "name 2")
	@NamedAnnotation3(name = "name 3")
	public static class NamedAnnotationsClass {
	}

	@NamedAnnotation1(name = "name 1")
	@NamedAnnotation2(name = "name 2")
	@NamedAnnotation3(name = "name 3")
	@Retention(RetentionPolicy.RUNTIME)
	@Target(ElementType.TYPE)
564
	@Inherited
565
	public @interface NamedComposedAnnotation {
566 567 568 569 570 571
	}

	@NamedComposedAnnotation
	public static class NamedComposedAnnotationClass {
	}

572 573 574
	public static class NamedComposedAnnotationExtended extends NamedComposedAnnotationClass {
	}

A
Arjen Poutsma 已提交
575
}