Skip to content

Commit 9bc9bdd

Browse files
committed
1 parent 02e90a8 commit 9bc9bdd

File tree

9 files changed

+116
-17
lines changed

9 files changed

+116
-17
lines changed

spring-context/src/test/java/example/gh24375/MyComponent.java renamed to spring-context/src/test/java/example/gh24375/AnnotatedComponent.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,6 @@
1919
import org.springframework.stereotype.Component;
2020

2121
@Component
22-
@A(other = @B)
23-
public class MyComponent {
22+
@EnclosingAnnotation(nested2 = @NestedAnnotation)
23+
public class AnnotatedComponent {
2424
}

spring-context/src/test/java/example/gh24375/A.java renamed to spring-context/src/test/java/example/gh24375/EnclosingAnnotation.java

+6-5
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,12 @@
2525

2626
@Target(ElementType.TYPE)
2727
@Retention(RetentionPolicy.RUNTIME)
28-
public @interface A {
28+
public @interface EnclosingAnnotation {
2929

30-
@AliasFor("value")
31-
B other() default @B;
30+
@AliasFor("nested2")
31+
NestedAnnotation nested1() default @NestedAnnotation;
32+
33+
@AliasFor("nested1")
34+
NestedAnnotation nested2() default @NestedAnnotation;
3235

33-
@AliasFor("other")
34-
B value() default @B;
3536
}

spring-context/src/test/java/example/gh24375/B.java renamed to spring-context/src/test/java/example/gh24375/NestedAnnotation.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@
2323

2424
@Target(ElementType.ANNOTATION_TYPE)
2525
@Retention(RetentionPolicy.RUNTIME)
26-
public @interface B {
26+
public @interface NestedAnnotation {
2727

2828
String name() default "";
29+
2930
}

spring-context/src/test/java/org/springframework/context/annotation/ClassPathScanningCandidateComponentProviderTests.java

+3-5
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
import java.util.Set;
2222
import java.util.regex.Pattern;
2323

24-
import example.gh24375.MyComponent;
24+
import example.gh24375.AnnotatedComponent;
2525
import example.profilescan.DevComponent;
2626
import example.profilescan.ProfileAnnotatedComponent;
2727
import example.profilescan.ProfileMetaAnnotatedComponent;
@@ -39,7 +39,6 @@
3939
import example.scannable.StubFooDao;
4040
import example.scannable.sub.BarComponent;
4141
import org.aspectj.lang.annotation.Aspect;
42-
import org.junit.jupiter.api.Disabled;
4342
import org.junit.jupiter.api.Test;
4443

4544
import org.springframework.beans.factory.annotation.AnnotatedGenericBeanDefinition;
@@ -503,12 +502,11 @@ public void testIntegrationWithAnnotationConfigApplicationContext_metaProfile()
503502
}
504503

505504
@Test
506-
@Disabled("Disabled until gh-24375 is resolved")
507505
public void gh24375() {
508506
ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(true);
509-
Set<BeanDefinition> components = provider.findCandidateComponents(MyComponent.class.getPackage().getName());
507+
Set<BeanDefinition> components = provider.findCandidateComponents(AnnotatedComponent.class.getPackage().getName());
510508
assertThat(components).hasSize(1);
511-
assertThat(components.iterator().next().getBeanClassName()).isEqualTo(MyComponent.class.getName());
509+
assertThat(components.iterator().next().getBeanClassName()).isEqualTo(AnnotatedComponent.class.getName());
512510
}
513511

514512

spring-core/src/main/java/org/springframework/core/annotation/AnnotationTypeMapping.java

+10-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2019 the original author or authors.
2+
* Copyright 2002-2020 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -534,8 +534,15 @@ private static boolean areEquivalent(Annotation annotation, @Nullable Object ext
534534
AttributeMethods attributes = AttributeMethods.forAnnotationType(annotation.annotationType());
535535
for (int i = 0; i < attributes.size(); i++) {
536536
Method attribute = attributes.get(i);
537-
if (!areEquivalent(ReflectionUtils.invokeMethod(attribute, annotation),
538-
valueExtractor.apply(attribute, extractedValue), valueExtractor)) {
537+
Object value1 = ReflectionUtils.invokeMethod(attribute, annotation);
538+
Object value2;
539+
if (extractedValue instanceof TypeMappedAnnotation) {
540+
value2 = ((TypeMappedAnnotation<?>) extractedValue).getValue(attribute.getName()).orElse(null);
541+
}
542+
else {
543+
value2 = valueExtractor.apply(attribute, extractedValue);
544+
}
545+
if (!areEquivalent(value1, value2, valueExtractor)) {
539546
return false;
540547
}
541548
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/*
2+
* Copyright 2002-2020 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package example.type;
18+
19+
@EnclosingAnnotation(nested2 = @NestedAnnotation)
20+
public class AnnotatedComponent {
21+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/*
2+
* Copyright 2002-2020 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package example.type;
18+
19+
import java.lang.annotation.Retention;
20+
import java.lang.annotation.RetentionPolicy;
21+
22+
import org.springframework.core.annotation.AliasFor;
23+
24+
@Retention(RetentionPolicy.RUNTIME)
25+
public @interface EnclosingAnnotation {
26+
27+
@AliasFor("nested2")
28+
NestedAnnotation nested1() default @NestedAnnotation;
29+
30+
@AliasFor("nested1")
31+
NestedAnnotation nested2() default @NestedAnnotation;
32+
33+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/*
2+
* Copyright 2002-2020 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package example.type;
18+
19+
import java.lang.annotation.ElementType;
20+
import java.lang.annotation.Retention;
21+
import java.lang.annotation.RetentionPolicy;
22+
import java.lang.annotation.Target;
23+
24+
@Target(ElementType.ANNOTATION_TYPE)
25+
@Retention(RetentionPolicy.RUNTIME)
26+
public @interface NestedAnnotation {
27+
28+
String name() default "";
29+
}

spring-core/src/test/java/org/springframework/core/type/AbstractMethodMetadataTests.java

+10-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2019 the original author or authors.
2+
* Copyright 2002-2020 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -19,6 +19,8 @@
1919
import java.lang.annotation.Retention;
2020
import java.lang.annotation.RetentionPolicy;
2121

22+
import example.type.AnnotatedComponent;
23+
import example.type.EnclosingAnnotation;
2224
import org.junit.jupiter.api.Test;
2325

2426
import org.springframework.core.annotation.MergedAnnotation;
@@ -31,6 +33,7 @@
3133
* Base class for {@link MethodMetadata} tests.
3234
*
3335
* @author Phillip Webb
36+
* @author Sam Brannen
3437
*/
3538
public abstract class AbstractMethodMetadataTests {
3639

@@ -138,6 +141,12 @@ public void getAllAnnotationAttributesReturnsAllAttributes() {
138141
assertThat(attributes.get("size")).containsExactlyInAnyOrder(1, 2);
139142
}
140143

144+
@Test // gh-24375
145+
public void metadataLoadsForNestedAnnotations() {
146+
AnnotationMetadata annotationMetadata = get(AnnotatedComponent.class);
147+
assertThat(annotationMetadata.getAnnotationTypes()).containsExactly(EnclosingAnnotation.class.getName());
148+
}
149+
141150
protected MethodMetadata getTagged(Class<?> source) {
142151
return get(source, Tag.class.getName());
143152
}

0 commit comments

Comments
 (0)