Refactor AnnotationUtils#findAllAnnotationAttributes

Remove all convenience variants of #findAllAnnotationAttributes and
refactor the remaining method to accept a MetadataReaderFactory
instead of creating its own SimpleMetadataReaderFactory internally.
This allows clients to use non-default class loaders as well as
customize the particular MetadataReaderFactory to be used (e.g.
'simple' vs 'caching', etc).

Issue: SPR-8752
This commit is contained in:
Chris Beams 2011-10-09 20:32:21 +00:00
parent 3bb01ee68b
commit 6837111bda
3 changed files with 16 additions and 25 deletions

View File

@ -210,7 +210,7 @@ class ConfigurationClassParser {
// process any @Import annotations
List<Map<String, Object>> allImportAttribs =
AnnotationUtils.findAllAnnotationAttributes(Import.class, metadata.getClassName(), true);
AnnotationUtils.findAllAnnotationAttributes(Import.class, metadata.getClassName(), true, metadataReaderFactory);
for (Map<String, Object> importAttribs : allImportAttribs) {
processImport(configClass, (String[]) importAttribs.get("value"), true);
}

View File

@ -30,6 +30,7 @@ import java.util.WeakHashMap;
import org.springframework.core.BridgeMethodResolver;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.MetadataReaderFactory;
import org.springframework.core.type.classreading.SimpleMetadataReaderFactory;
import org.springframework.util.Assert;
@ -354,22 +355,24 @@ public abstract class AnnotationUtils {
}
/**
* Return a list of attribute maps for all declarations of the given target annotation
* on the given annotated class. Meta annotations are ordered first in the list, and if
* the target annotation is declared directly on the class, its map of attributes will be
* Return a list of attribute maps for all declarations of the given annotation
* on the given annotated class using the given MetadataReaderFactory to introspect
* annotation metadata. Meta-annotations are ordered first in the list, and if the
* target annotation is declared directly on the class, its map of attributes will be
* ordered last in the list.
* @param targetAnnotation the annotation to search for, both locally and as a meta-annotation
* @param annotatedClassName the class to search
* @param annotatedClassName the class to inspect
* @param classValuesAsString whether class attributes should be returned as strings
* @param metadataReaderFactory factory used to create metadata readers for each type
* @since 3.1
* @see {@link #findAllAnnotationAttributes(Class, String)}
*/
public static List<Map<String, Object>> findAllAnnotationAttributes(
Class<? extends Annotation> targetAnnotation, String annotatedClassName, boolean classValuesAsString) throws IOException {
Class<? extends Annotation> targetAnnotation, String annotatedClassName,
boolean classValuesAsString, MetadataReaderFactory metadataReaderFactory) throws IOException {
List<Map<String, Object>> allAttribs = new ArrayList<Map<String, Object>>();
MetadataReader reader = new SimpleMetadataReaderFactory().getMetadataReader(annotatedClassName);
MetadataReader reader = metadataReaderFactory.getMetadataReader(annotatedClassName);
AnnotationMetadata metadata = reader.getAnnotationMetadata();
String targetAnnotationType = targetAnnotation.getName();
@ -377,7 +380,7 @@ public abstract class AnnotationUtils {
if (annotationType.equals(targetAnnotationType)) {
continue;
}
MetadataReader metaReader = new SimpleMetadataReaderFactory().getMetadataReader(annotationType);
MetadataReader metaReader = metadataReaderFactory.getMetadataReader(annotationType);
Map<String, Object> targetAttribs =
metaReader.getAnnotationMetadata().getAnnotationAttributes(targetAnnotationType, classValuesAsString);
if (targetAttribs != null) {
@ -394,21 +397,6 @@ public abstract class AnnotationUtils {
return allAttribs;
}
/**
* Return a list of attribute maps for all declarations of the given target annotation
* on the given annotated class. Meta annotations are ordered first in the list, and if
* the target annotation is declared directly on the class, its map of attributes will be
* ordered last in the list.
* @param targetAnnotation the annotation to search for, both locally and as a meta-annotation
* @param annotatedClassName the class to search
* @since 3.1
* @see {@link #findAllAnnotationAttributes(Class, String, boolean)}
*/
public static List<Map<String, Object>> findAllAnnotationAttributes(
Class<? extends Annotation> targetAnnotation, String annotatedClassName) throws IOException {
return findAllAnnotationAttributes(targetAnnotation, annotatedClassName, false);
}
/**
* Retrieve the <em>value</em> of the <code>&quot;value&quot;</code> attribute of a
* single-element Annotation, given an annotation instance.

View File

@ -39,6 +39,7 @@ import java.util.Map;
import org.junit.Test;
import org.springframework.core.Ordered;
import org.springframework.core.type.classreading.SimpleMetadataReaderFactory;
import org.springframework.stereotype.Component;
/**
@ -221,7 +222,9 @@ public class AnnotationUtilsTests {
@Test
public void findAllComponentAnnotationAttributes() throws IOException {
List<Map<String,Object>> allAttribs =
AnnotationUtils.findAllAnnotationAttributes(Component.class, HasLocalAndMetaComponentAnnotation.class.getName());
AnnotationUtils.findAllAnnotationAttributes(Component.class,
HasLocalAndMetaComponentAnnotation.class.getName(), false,
new SimpleMetadataReaderFactory());
Object value = null;
for (Map<String, Object> attribs : allAttribs) {