Skip to content

Commit 3430f76

Browse files
committed
Consistent detection of meta-annotation attributes via ASM
Issue: SPR-13394
1 parent 6aa9e0c commit 3430f76

File tree

5 files changed

+59
-23
lines changed

5 files changed

+59
-23
lines changed

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

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727

2828
import org.springframework.aop.scope.ScopedObject;
2929
import org.springframework.aop.scope.ScopedProxyUtils;
30+
import org.springframework.aop.support.AopUtils;
3031
import org.springframework.beans.factory.BeanCreationException;
3132
import org.springframework.beans.factory.BeanDefinitionStoreException;
3233
import org.springframework.beans.factory.FactoryBean;
@@ -426,6 +427,28 @@ public void genericsBasedInjectionWithScopedProxy() {
426427
RepositoryInjectionBean bean = (RepositoryInjectionBean) beanFactory.getBean("annotatedBean");
427428
assertEquals("Repository<String>", bean.stringRepository.toString());
428429
assertEquals("Repository<Integer>", bean.integerRepository.toString());
430+
assertTrue(AopUtils.isCglibProxy(bean.stringRepository));
431+
assertTrue(AopUtils.isCglibProxy(bean.integerRepository));
432+
}
433+
434+
@Test
435+
public void genericsBasedInjectionWithScopedProxyUsingAsm() {
436+
AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
437+
bpp.setBeanFactory(beanFactory);
438+
beanFactory.addBeanPostProcessor(bpp);
439+
RootBeanDefinition bd = new RootBeanDefinition(RepositoryInjectionBean.class.getName());
440+
bd.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
441+
beanFactory.registerBeanDefinition("annotatedBean", bd);
442+
beanFactory.registerBeanDefinition("configClass", new RootBeanDefinition(ScopedProxyRepositoryConfiguration.class.getName()));
443+
ConfigurationClassPostProcessor pp = new ConfigurationClassPostProcessor();
444+
pp.postProcessBeanFactory(beanFactory);
445+
beanFactory.freezeConfiguration();
446+
447+
RepositoryInjectionBean bean = (RepositoryInjectionBean) beanFactory.getBean("annotatedBean");
448+
assertEquals("Repository<String>", bean.stringRepository.toString());
449+
assertEquals("Repository<Integer>", bean.integerRepository.toString());
450+
assertTrue(AopUtils.isCglibProxy(bean.stringRepository));
451+
assertTrue(AopUtils.isCglibProxy(bean.integerRepository));
429452
}
430453

431454
@Test
@@ -783,6 +806,13 @@ public String toString() {
783806
}
784807
}
785808

809+
@Retention(RetentionPolicy.RUNTIME)
810+
@Scope(scopeName = "prototype")
811+
public @interface PrototypeScoped {
812+
813+
ScopedProxyMode proxyMode() default ScopedProxyMode.TARGET_CLASS;
814+
}
815+
786816
@Configuration
787817
public static class ScopedProxyRepositoryConfiguration {
788818

@@ -798,7 +828,7 @@ public String toString() {
798828
}
799829

800830
@Bean
801-
@Scope(scopeName = "prototype", proxyMode = ScopedProxyMode.TARGET_CLASS)
831+
@PrototypeScoped
802832
public Repository<Integer> integerRepo() {
803833
return new Repository<Integer>() {
804834
@Override

spring-core/src/main/java/org/springframework/core/type/StandardAnnotationMetadata.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ public Map<String, Object> getAnnotationAttributes(String annotationName) {
111111
@Override
112112
public Map<String, Object> getAnnotationAttributes(String annotationName, boolean classValuesAsString) {
113113
return AnnotatedElementUtils.getMergedAnnotationAttributes(getIntrospectedClass(),
114-
annotationName, classValuesAsString, this.nestedAnnotationsAsMap);
114+
annotationName, classValuesAsString, this.nestedAnnotationsAsMap);
115115
}
116116

117117
@Override
@@ -122,7 +122,7 @@ public MultiValueMap<String, Object> getAllAnnotationAttributes(String annotatio
122122
@Override
123123
public MultiValueMap<String, Object> getAllAnnotationAttributes(String annotationName, boolean classValuesAsString) {
124124
return AnnotatedElementUtils.getAllAnnotationAttributes(getIntrospectedClass(),
125-
annotationName, classValuesAsString, this.nestedAnnotationsAsMap);
125+
annotationName, classValuesAsString, this.nestedAnnotationsAsMap);
126126
}
127127

128128
@Override

spring-core/src/main/java/org/springframework/core/type/StandardMethodMetadata.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ public StandardMethodMetadata(Method introspectedMethod, boolean nestedAnnotatio
6666
this.nestedAnnotationsAsMap = nestedAnnotationsAsMap;
6767
}
6868

69+
6970
/**
7071
* Return the underlying Method.
7172
*/
@@ -121,7 +122,7 @@ public Map<String, Object> getAnnotationAttributes(String annotationName) {
121122
@Override
122123
public Map<String, Object> getAnnotationAttributes(String annotationName, boolean classValuesAsString) {
123124
return AnnotatedElementUtils.getMergedAnnotationAttributes(this.introspectedMethod,
124-
annotationName, classValuesAsString, this.nestedAnnotationsAsMap);
125+
annotationName, classValuesAsString, this.nestedAnnotationsAsMap);
125126
}
126127

127128
@Override
@@ -132,7 +133,7 @@ public MultiValueMap<String, Object> getAllAnnotationAttributes(String annotatio
132133
@Override
133134
public MultiValueMap<String, Object> getAllAnnotationAttributes(String annotationName, boolean classValuesAsString) {
134135
return AnnotatedElementUtils.getAllAnnotationAttributes(this.introspectedMethod,
135-
annotationName, classValuesAsString, this.nestedAnnotationsAsMap);
136+
annotationName, classValuesAsString, this.nestedAnnotationsAsMap);
136137
}
137138

138139
}

spring-core/src/main/java/org/springframework/core/type/classreading/AnnotationMetadataReadingVisitor.java

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,8 @@ public class AnnotationMetadataReadingVisitor extends ClassMetadataReadingVisito
5959
* to ensure that the hierarchical ordering of the entries is preserved.
6060
* @see AnnotationReadingVisitorUtils#getMergedAnnotationAttributes
6161
*/
62-
protected final LinkedMultiValueMap<String, AnnotationAttributes> attributesMap = new LinkedMultiValueMap<String, AnnotationAttributes>(4);
62+
protected final LinkedMultiValueMap<String, AnnotationAttributes> attributesMap =
63+
new LinkedMultiValueMap<String, AnnotationAttributes>(4);
6364

6465
protected final Set<MethodMetadata> methodMetadataSet = new LinkedHashSet<MethodMetadata>(4);
6566

@@ -84,7 +85,8 @@ public MethodVisitor visitMethod(int access, String name, String desc, String si
8485
public AnnotationVisitor visitAnnotation(final String desc, boolean visible) {
8586
String className = Type.getType(desc).getClassName();
8687
this.annotationSet.add(className);
87-
return new AnnotationAttributesReadingVisitor(className, this.attributesMap, this.metaAnnotationMap, this.classLoader);
88+
return new AnnotationAttributesReadingVisitor(
89+
className, this.attributesMap, this.metaAnnotationMap, this.classLoader);
8890
}
8991

9092

@@ -116,7 +118,8 @@ public boolean hasMetaAnnotation(String metaAnnotationType) {
116118

117119
@Override
118120
public boolean isAnnotated(String annotationName) {
119-
return (!AnnotationUtils.isInJavaLangAnnotationPackage(annotationName) && this.attributesMap.containsKey(annotationName));
121+
return (!AnnotationUtils.isInJavaLangAnnotationPackage(annotationName) &&
122+
this.attributesMap.containsKey(annotationName));
120123
}
121124

122125
@Override
@@ -127,8 +130,7 @@ public AnnotationAttributes getAnnotationAttributes(String annotationName) {
127130
@Override
128131
public AnnotationAttributes getAnnotationAttributes(String annotationName, boolean classValuesAsString) {
129132
AnnotationAttributes raw = AnnotationReadingVisitorUtils.getMergedAnnotationAttributes(
130-
this.attributesMap,
131-
this.metaAnnotationMap, annotationName);
133+
this.attributesMap, this.metaAnnotationMap, annotationName);
132134
return AnnotationReadingVisitorUtils.convertClassValues(this.classLoader, raw, classValuesAsString);
133135
}
134136

@@ -145,8 +147,8 @@ public MultiValueMap<String, Object> getAllAnnotationAttributes(String annotatio
145147
return null;
146148
}
147149
for (AnnotationAttributes raw : attributes) {
148-
for (Map.Entry<String, Object> entry :
149-
AnnotationReadingVisitorUtils.convertClassValues(this.classLoader, raw, classValuesAsString).entrySet()) {
150+
for (Map.Entry<String, Object> entry : AnnotationReadingVisitorUtils.convertClassValues(
151+
this.classLoader, raw, classValuesAsString).entrySet()) {
150152
allAttributes.add(entry.getKey(), entry.getValue());
151153
}
152154
}

spring-core/src/main/java/org/springframework/core/type/classreading/MethodMetadataReadingVisitor.java

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
package org.springframework.core.type.classreading;
1818

19-
import java.util.List;
19+
import java.util.LinkedHashMap;
2020
import java.util.Map;
2121
import java.util.Set;
2222

@@ -56,7 +56,9 @@ public class MethodMetadataReadingVisitor extends MethodVisitor implements Metho
5656

5757
protected final Set<MethodMetadata> methodMetadataSet;
5858

59-
protected final MultiValueMap<String, AnnotationAttributes> attributeMap =
59+
protected final Map<String, Set<String>> metaAnnotationMap = new LinkedHashMap<String, Set<String>>(4);
60+
61+
protected final LinkedMultiValueMap<String, AnnotationAttributes> attributesMap =
6062
new LinkedMultiValueMap<String, AnnotationAttributes>(4);
6163

6264

@@ -77,7 +79,8 @@ public MethodMetadataReadingVisitor(String methodName, int access, String declar
7779
public AnnotationVisitor visitAnnotation(final String desc, boolean visible) {
7880
String className = Type.getType(desc).getClassName();
7981
this.methodMetadataSet.add(this);
80-
return new AnnotationAttributesReadingVisitor(className, this.attributeMap, null, this.classLoader);
82+
return new AnnotationAttributesReadingVisitor(
83+
className, this.attributesMap, this.metaAnnotationMap, this.classLoader);
8184
}
8285

8386
@Override
@@ -107,19 +110,19 @@ public boolean isOverridable() {
107110

108111
@Override
109112
public boolean isAnnotated(String annotationName) {
110-
return this.attributeMap.containsKey(annotationName);
113+
return this.attributesMap.containsKey(annotationName);
111114
}
112115

113116
@Override
114-
public Map<String, Object> getAnnotationAttributes(String annotationName) {
117+
public AnnotationAttributes getAnnotationAttributes(String annotationName) {
115118
return getAnnotationAttributes(annotationName, false);
116119
}
117120

118121
@Override
119-
public Map<String, Object> getAnnotationAttributes(String annotationName, boolean classValuesAsString) {
120-
List<AnnotationAttributes> attributes = this.attributeMap.get(annotationName);
121-
return (attributes == null ? null : AnnotationReadingVisitorUtils.convertClassValues(
122-
this.classLoader, attributes.get(0), classValuesAsString));
122+
public AnnotationAttributes getAnnotationAttributes(String annotationName, boolean classValuesAsString) {
123+
AnnotationAttributes raw = AnnotationReadingVisitorUtils.getMergedAnnotationAttributes(
124+
this.attributesMap, this.metaAnnotationMap, annotationName);
125+
return (AnnotationReadingVisitorUtils.convertClassValues(this.classLoader, raw, classValuesAsString));
123126
}
124127

125128
@Override
@@ -129,11 +132,11 @@ public MultiValueMap<String, Object> getAllAnnotationAttributes(String annotatio
129132

130133
@Override
131134
public MultiValueMap<String, Object> getAllAnnotationAttributes(String annotationName, boolean classValuesAsString) {
132-
if (!this.attributeMap.containsKey(annotationName)) {
135+
if (!this.attributesMap.containsKey(annotationName)) {
133136
return null;
134137
}
135138
MultiValueMap<String, Object> allAttributes = new LinkedMultiValueMap<String, Object>();
136-
for (AnnotationAttributes annotationAttributes : this.attributeMap.get(annotationName)) {
139+
for (AnnotationAttributes annotationAttributes : this.attributesMap.get(annotationName)) {
137140
for (Map.Entry<String, Object> entry : AnnotationReadingVisitorUtils.convertClassValues(
138141
this.classLoader, annotationAttributes, classValuesAsString).entrySet()) {
139142
allAttributes.add(entry.getKey(), entry.getValue());

0 commit comments

Comments
 (0)