Consistent detection of meta-annotation attributes via ASM
Issue: SPR-13394
This commit is contained in:
parent
6aa9e0caf9
commit
3430f7623c
|
@ -27,6 +27,7 @@ import org.junit.Test;
|
|||
|
||||
import org.springframework.aop.scope.ScopedObject;
|
||||
import org.springframework.aop.scope.ScopedProxyUtils;
|
||||
import org.springframework.aop.support.AopUtils;
|
||||
import org.springframework.beans.factory.BeanCreationException;
|
||||
import org.springframework.beans.factory.BeanDefinitionStoreException;
|
||||
import org.springframework.beans.factory.FactoryBean;
|
||||
|
@ -426,6 +427,28 @@ public class ConfigurationClassPostProcessorTests {
|
|||
RepositoryInjectionBean bean = (RepositoryInjectionBean) beanFactory.getBean("annotatedBean");
|
||||
assertEquals("Repository<String>", bean.stringRepository.toString());
|
||||
assertEquals("Repository<Integer>", bean.integerRepository.toString());
|
||||
assertTrue(AopUtils.isCglibProxy(bean.stringRepository));
|
||||
assertTrue(AopUtils.isCglibProxy(bean.integerRepository));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void genericsBasedInjectionWithScopedProxyUsingAsm() {
|
||||
AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
|
||||
bpp.setBeanFactory(beanFactory);
|
||||
beanFactory.addBeanPostProcessor(bpp);
|
||||
RootBeanDefinition bd = new RootBeanDefinition(RepositoryInjectionBean.class.getName());
|
||||
bd.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
|
||||
beanFactory.registerBeanDefinition("annotatedBean", bd);
|
||||
beanFactory.registerBeanDefinition("configClass", new RootBeanDefinition(ScopedProxyRepositoryConfiguration.class.getName()));
|
||||
ConfigurationClassPostProcessor pp = new ConfigurationClassPostProcessor();
|
||||
pp.postProcessBeanFactory(beanFactory);
|
||||
beanFactory.freezeConfiguration();
|
||||
|
||||
RepositoryInjectionBean bean = (RepositoryInjectionBean) beanFactory.getBean("annotatedBean");
|
||||
assertEquals("Repository<String>", bean.stringRepository.toString());
|
||||
assertEquals("Repository<Integer>", bean.integerRepository.toString());
|
||||
assertTrue(AopUtils.isCglibProxy(bean.stringRepository));
|
||||
assertTrue(AopUtils.isCglibProxy(bean.integerRepository));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -783,6 +806,13 @@ public class ConfigurationClassPostProcessorTests {
|
|||
}
|
||||
}
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Scope(scopeName = "prototype")
|
||||
public @interface PrototypeScoped {
|
||||
|
||||
ScopedProxyMode proxyMode() default ScopedProxyMode.TARGET_CLASS;
|
||||
}
|
||||
|
||||
@Configuration
|
||||
public static class ScopedProxyRepositoryConfiguration {
|
||||
|
||||
|
@ -798,7 +828,7 @@ public class ConfigurationClassPostProcessorTests {
|
|||
}
|
||||
|
||||
@Bean
|
||||
@Scope(scopeName = "prototype", proxyMode = ScopedProxyMode.TARGET_CLASS)
|
||||
@PrototypeScoped
|
||||
public Repository<Integer> integerRepo() {
|
||||
return new Repository<Integer>() {
|
||||
@Override
|
||||
|
|
|
@ -66,6 +66,7 @@ public class StandardMethodMetadata implements MethodMetadata {
|
|||
this.nestedAnnotationsAsMap = nestedAnnotationsAsMap;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the underlying Method.
|
||||
*/
|
||||
|
|
|
@ -59,7 +59,8 @@ public class AnnotationMetadataReadingVisitor extends ClassMetadataReadingVisito
|
|||
* to ensure that the hierarchical ordering of the entries is preserved.
|
||||
* @see AnnotationReadingVisitorUtils#getMergedAnnotationAttributes
|
||||
*/
|
||||
protected final LinkedMultiValueMap<String, AnnotationAttributes> attributesMap = new LinkedMultiValueMap<String, AnnotationAttributes>(4);
|
||||
protected final LinkedMultiValueMap<String, AnnotationAttributes> attributesMap =
|
||||
new LinkedMultiValueMap<String, AnnotationAttributes>(4);
|
||||
|
||||
protected final Set<MethodMetadata> methodMetadataSet = new LinkedHashSet<MethodMetadata>(4);
|
||||
|
||||
|
@ -84,7 +85,8 @@ public class AnnotationMetadataReadingVisitor extends ClassMetadataReadingVisito
|
|||
public AnnotationVisitor visitAnnotation(final String desc, boolean visible) {
|
||||
String className = Type.getType(desc).getClassName();
|
||||
this.annotationSet.add(className);
|
||||
return new AnnotationAttributesReadingVisitor(className, this.attributesMap, this.metaAnnotationMap, this.classLoader);
|
||||
return new AnnotationAttributesReadingVisitor(
|
||||
className, this.attributesMap, this.metaAnnotationMap, this.classLoader);
|
||||
}
|
||||
|
||||
|
||||
|
@ -116,7 +118,8 @@ public class AnnotationMetadataReadingVisitor extends ClassMetadataReadingVisito
|
|||
|
||||
@Override
|
||||
public boolean isAnnotated(String annotationName) {
|
||||
return (!AnnotationUtils.isInJavaLangAnnotationPackage(annotationName) && this.attributesMap.containsKey(annotationName));
|
||||
return (!AnnotationUtils.isInJavaLangAnnotationPackage(annotationName) &&
|
||||
this.attributesMap.containsKey(annotationName));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -127,8 +130,7 @@ public class AnnotationMetadataReadingVisitor extends ClassMetadataReadingVisito
|
|||
@Override
|
||||
public AnnotationAttributes getAnnotationAttributes(String annotationName, boolean classValuesAsString) {
|
||||
AnnotationAttributes raw = AnnotationReadingVisitorUtils.getMergedAnnotationAttributes(
|
||||
this.attributesMap,
|
||||
this.metaAnnotationMap, annotationName);
|
||||
this.attributesMap, this.metaAnnotationMap, annotationName);
|
||||
return AnnotationReadingVisitorUtils.convertClassValues(this.classLoader, raw, classValuesAsString);
|
||||
}
|
||||
|
||||
|
@ -145,8 +147,8 @@ this.attributesMap,
|
|||
return null;
|
||||
}
|
||||
for (AnnotationAttributes raw : attributes) {
|
||||
for (Map.Entry<String, Object> entry :
|
||||
AnnotationReadingVisitorUtils.convertClassValues(this.classLoader, raw, classValuesAsString).entrySet()) {
|
||||
for (Map.Entry<String, Object> entry : AnnotationReadingVisitorUtils.convertClassValues(
|
||||
this.classLoader, raw, classValuesAsString).entrySet()) {
|
||||
allAttributes.add(entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
package org.springframework.core.type.classreading;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
|
@ -56,7 +56,9 @@ public class MethodMetadataReadingVisitor extends MethodVisitor implements Metho
|
|||
|
||||
protected final Set<MethodMetadata> methodMetadataSet;
|
||||
|
||||
protected final MultiValueMap<String, AnnotationAttributes> attributeMap =
|
||||
protected final Map<String, Set<String>> metaAnnotationMap = new LinkedHashMap<String, Set<String>>(4);
|
||||
|
||||
protected final LinkedMultiValueMap<String, AnnotationAttributes> attributesMap =
|
||||
new LinkedMultiValueMap<String, AnnotationAttributes>(4);
|
||||
|
||||
|
||||
|
@ -77,7 +79,8 @@ public class MethodMetadataReadingVisitor extends MethodVisitor implements Metho
|
|||
public AnnotationVisitor visitAnnotation(final String desc, boolean visible) {
|
||||
String className = Type.getType(desc).getClassName();
|
||||
this.methodMetadataSet.add(this);
|
||||
return new AnnotationAttributesReadingVisitor(className, this.attributeMap, null, this.classLoader);
|
||||
return new AnnotationAttributesReadingVisitor(
|
||||
className, this.attributesMap, this.metaAnnotationMap, this.classLoader);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -107,19 +110,19 @@ public class MethodMetadataReadingVisitor extends MethodVisitor implements Metho
|
|||
|
||||
@Override
|
||||
public boolean isAnnotated(String annotationName) {
|
||||
return this.attributeMap.containsKey(annotationName);
|
||||
return this.attributesMap.containsKey(annotationName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getAnnotationAttributes(String annotationName) {
|
||||
public AnnotationAttributes getAnnotationAttributes(String annotationName) {
|
||||
return getAnnotationAttributes(annotationName, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getAnnotationAttributes(String annotationName, boolean classValuesAsString) {
|
||||
List<AnnotationAttributes> attributes = this.attributeMap.get(annotationName);
|
||||
return (attributes == null ? null : AnnotationReadingVisitorUtils.convertClassValues(
|
||||
this.classLoader, attributes.get(0), classValuesAsString));
|
||||
public AnnotationAttributes getAnnotationAttributes(String annotationName, boolean classValuesAsString) {
|
||||
AnnotationAttributes raw = AnnotationReadingVisitorUtils.getMergedAnnotationAttributes(
|
||||
this.attributesMap, this.metaAnnotationMap, annotationName);
|
||||
return (AnnotationReadingVisitorUtils.convertClassValues(this.classLoader, raw, classValuesAsString));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -129,11 +132,11 @@ public class MethodMetadataReadingVisitor extends MethodVisitor implements Metho
|
|||
|
||||
@Override
|
||||
public MultiValueMap<String, Object> getAllAnnotationAttributes(String annotationName, boolean classValuesAsString) {
|
||||
if (!this.attributeMap.containsKey(annotationName)) {
|
||||
if (!this.attributesMap.containsKey(annotationName)) {
|
||||
return null;
|
||||
}
|
||||
MultiValueMap<String, Object> allAttributes = new LinkedMultiValueMap<String, Object>();
|
||||
for (AnnotationAttributes annotationAttributes : this.attributeMap.get(annotationName)) {
|
||||
for (AnnotationAttributes annotationAttributes : this.attributesMap.get(annotationName)) {
|
||||
for (Map.Entry<String, Object> entry : AnnotationReadingVisitorUtils.convertClassValues(
|
||||
this.classLoader, annotationAttributes, classValuesAsString).entrySet()) {
|
||||
allAttributes.add(entry.getKey(), entry.getValue());
|
||||
|
|
Loading…
Reference in New Issue