Fixed @Bean meta-annotation detection when using ASM
This turned out to be a bug in the ASM-based AnnotationMetadata implementation where has/getAnnotatedMethods didn't consider meta-annotations., in contrast to its StandardAnnotationMetadata sibling. Issue: SPR-10488
This commit is contained in:
parent
61a3d04e91
commit
105e176a80
|
@ -23,6 +23,7 @@ import org.junit.Test;
|
|||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
@ -84,6 +85,19 @@ public class BeanMethodQualificationTests {
|
|||
assertThat(pojo.testBean.getName(), equalTo("interesting"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCustomWithAsm() {
|
||||
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
|
||||
ctx.registerBeanDefinition("customConfig", new RootBeanDefinition(CustomConfig.class.getName()));
|
||||
RootBeanDefinition customPojo = new RootBeanDefinition(CustomPojo.class.getName());
|
||||
customPojo.setLazyInit(true);
|
||||
ctx.registerBeanDefinition("customPojo", customPojo);
|
||||
ctx.refresh();
|
||||
assertFalse(ctx.getBeanFactory().containsSingleton("testBean1"));
|
||||
CustomPojo pojo = ctx.getBean(CustomPojo.class);
|
||||
assertThat(pojo.testBean.getName(), equalTo("interesting"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCustomWithAttributeOverride() {
|
||||
AnnotationConfigApplicationContext ctx =
|
||||
|
|
|
@ -29,7 +29,6 @@ import org.springframework.asm.Type;
|
|||
import org.springframework.core.annotation.AnnotationAttributes;
|
||||
import org.springframework.core.type.AnnotationMetadata;
|
||||
import org.springframework.core.type.MethodMetadata;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.LinkedMultiValueMap;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
|
||||
|
@ -48,13 +47,13 @@ public class AnnotationMetadataReadingVisitor extends ClassMetadataReadingVisito
|
|||
|
||||
protected final ClassLoader classLoader;
|
||||
|
||||
protected final Set<String> annotationSet = new LinkedHashSet<String>();
|
||||
protected final Set<String> annotationSet = new LinkedHashSet<String>(4);
|
||||
|
||||
protected final Map<String, Set<String>> metaAnnotationMap = new LinkedHashMap<String, Set<String>>(4);
|
||||
|
||||
protected final MultiValueMap<String, AnnotationAttributes> attributeMap = new LinkedMultiValueMap<String, AnnotationAttributes>(4);
|
||||
|
||||
protected final MultiValueMap<String, MethodMetadata> methodMetadataMap = new LinkedMultiValueMap<String, MethodMetadata>();
|
||||
protected final Set<MethodMetadata> methodMetadataSet = new LinkedHashSet<MethodMetadata>(4);
|
||||
|
||||
|
||||
public AnnotationMetadataReadingVisitor(ClassLoader classLoader) {
|
||||
|
@ -64,7 +63,7 @@ public class AnnotationMetadataReadingVisitor extends ClassMetadataReadingVisito
|
|||
|
||||
@Override
|
||||
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
|
||||
return new MethodMetadataReadingVisitor(name, access, this.getClassName(), this.classLoader, this.methodMetadataMap);
|
||||
return new MethodMetadataReadingVisitor(name, access, getClassName(), this.classLoader, this.methodMetadataSet);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -141,17 +140,22 @@ public class AnnotationMetadataReadingVisitor extends ClassMetadataReadingVisito
|
|||
|
||||
@Override
|
||||
public boolean hasAnnotatedMethods(String annotationType) {
|
||||
return this.methodMetadataMap.containsKey(annotationType);
|
||||
for (MethodMetadata methodMetadata : this.methodMetadataSet) {
|
||||
if (methodMetadata.isAnnotated(annotationType)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<MethodMetadata> getAnnotatedMethods(String annotationType) {
|
||||
List<MethodMetadata> list = this.methodMetadataMap.get(annotationType);
|
||||
if (CollectionUtils.isEmpty(list)) {
|
||||
return new LinkedHashSet<MethodMetadata>(0);
|
||||
Set<MethodMetadata> annotatedMethods = new LinkedHashSet<MethodMetadata>(4);
|
||||
for (MethodMetadata methodMetadata : this.methodMetadataSet) {
|
||||
if (methodMetadata.isAnnotated(annotationType)) {
|
||||
annotatedMethods.add(methodMetadata);
|
||||
}
|
||||
}
|
||||
Set<MethodMetadata> annotatedMethods = new LinkedHashSet<MethodMetadata>(list.size());
|
||||
annotatedMethods.addAll(list);
|
||||
return annotatedMethods;
|
||||
}
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@ package org.springframework.core.type.classreading;
|
|||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.asm.AnnotationVisitor;
|
||||
import org.springframework.asm.MethodVisitor;
|
||||
|
@ -51,27 +52,28 @@ public class MethodMetadataReadingVisitor extends MethodVisitor implements Metho
|
|||
|
||||
protected final ClassLoader classLoader;
|
||||
|
||||
protected final MultiValueMap<String, MethodMetadata> methodMetadataMap;
|
||||
protected final Set<MethodMetadata> methodMetadataSet;
|
||||
|
||||
protected final MultiValueMap<String, AnnotationAttributes> attributeMap = new LinkedMultiValueMap<String, AnnotationAttributes>(2);
|
||||
protected final MultiValueMap<String, AnnotationAttributes> attributeMap =
|
||||
new LinkedMultiValueMap<String, AnnotationAttributes>(4);
|
||||
|
||||
|
||||
public MethodMetadataReadingVisitor(String name, int access, String declaringClassName, ClassLoader classLoader,
|
||||
MultiValueMap<String, MethodMetadata> methodMetadataMap) {
|
||||
public MethodMetadataReadingVisitor(String name, int access, String declaringClassName,
|
||||
ClassLoader classLoader, Set<MethodMetadata> methodMetadataSet) {
|
||||
|
||||
super(SpringAsmInfo.ASM_VERSION);
|
||||
this.name = name;
|
||||
this.access = access;
|
||||
this.declaringClassName = declaringClassName;
|
||||
this.classLoader = classLoader;
|
||||
this.methodMetadataMap = methodMetadataMap;
|
||||
this.methodMetadataSet = methodMetadataSet;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public AnnotationVisitor visitAnnotation(final String desc, boolean visible) {
|
||||
String className = Type.getType(desc).getClassName();
|
||||
this.methodMetadataMap.add(className, this);
|
||||
this.methodMetadataSet.add(this);
|
||||
return new AnnotationAttributesReadingVisitor(className, this.attributeMap, null, this.classLoader);
|
||||
}
|
||||
|
||||
|
@ -106,8 +108,7 @@ public class MethodMetadataReadingVisitor extends MethodVisitor implements Metho
|
|||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getAnnotationAttributes(String annotationType,
|
||||
boolean classValuesAsString) {
|
||||
public Map<String, Object> getAnnotationAttributes(String annotationType, boolean classValuesAsString) {
|
||||
List<AnnotationAttributes> attributes = this.attributeMap.get(annotationType);
|
||||
return (attributes == null ? null : AnnotationReadingVisitorUtils.convertClassValues(
|
||||
this.classLoader, attributes.get(0), classValuesAsString));
|
||||
|
@ -119,9 +120,8 @@ public class MethodMetadataReadingVisitor extends MethodVisitor implements Metho
|
|||
}
|
||||
|
||||
@Override
|
||||
public MultiValueMap<String, Object> getAllAnnotationAttributes(
|
||||
String annotationType, boolean classValuesAsString) {
|
||||
if(!this.attributeMap.containsKey(annotationType)) {
|
||||
public MultiValueMap<String, Object> getAllAnnotationAttributes(String annotationType, boolean classValuesAsString) {
|
||||
if (!this.attributeMap.containsKey(annotationType)) {
|
||||
return null;
|
||||
}
|
||||
MultiValueMap<String, Object> allAttributes = new LinkedMultiValueMap<String, Object>();
|
||||
|
|
Loading…
Reference in New Issue