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
master
Juergen Hoeller 11 years ago
parent 61a3d04e91
commit 105e176a80
  1. 14
      spring-context/src/test/java/org/springframework/context/annotation/configuration/BeanMethodQualificationTests.java
  2. 24
      spring-core/src/main/java/org/springframework/core/type/classreading/AnnotationMetadataReadingVisitor.java
  3. 22
      spring-core/src/main/java/org/springframework/core/type/classreading/MethodMetadataReadingVisitor.java

@ -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…
Cancel
Save