Polishing

Issue: SPR-10609
This commit is contained in:
Juergen Hoeller 2013-07-30 20:53:31 +02:00 committed by unknown
parent 3482c170e0
commit 481aeeec98
2 changed files with 57 additions and 81 deletions

View File

@ -185,8 +185,7 @@ class ConfigurationClassParser {
protected void processConfigurationClass(ConfigurationClass configClass) throws IOException { protected void processConfigurationClass(ConfigurationClass configClass) throws IOException {
if (this.conditionEvaluator.shouldSkip(configClass.getMetadata(), ConfigurationPhase.PARSE_CONFIGURATION)) {
if (conditionEvaluator.shouldSkip(configClass.getMetadata(), ConfigurationPhase.PARSE_CONFIGURATION)) {
return; return;
} }
@ -219,9 +218,7 @@ class ConfigurationClassParser {
* @param sourceClass a source class * @param sourceClass a source class
* @return the superclass, {@code null} if none found or previously processed * @return the superclass, {@code null} if none found or previously processed
*/ */
protected final SourceClass doProcessConfigurationClass( protected final SourceClass doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass) throws IOException {
ConfigurationClass configClass, SourceClass sourceClass) throws IOException {
// recursively process any member (nested) classes first // recursively process any member (nested) classes first
processMemberClasses(configClass, sourceClass); processMemberClasses(configClass, sourceClass);
@ -350,18 +347,15 @@ class ConfigurationClassParser {
* meta-annotations it is valid to have several {@code @Import}s declared with * meta-annotations it is valid to have several {@code @Import}s declared with
* different values, the usual process or returning values from the first * different values, the usual process or returning values from the first
* meta-annotation on a class is not sufficient. * meta-annotation on a class is not sufficient.
* <p> * <p>For example, it is common for a {@code @Configuration} class to declare direct
* For example, it is common for a {@code @Configuration} class to declare direct
* {@code @Import}s in addition to meta-imports originating from an {@code @Enable} * {@code @Import}s in addition to meta-imports originating from an {@code @Enable}
* annotation. * annotation.
*
* @param sourceClass the class to search * @param sourceClass the class to search
* @param imports the imports collected so far * @param imports the imports collected so far
* @param visited used to track visited classes to prevent infinite recursion * @param visited used to track visited classes to prevent infinite recursion
* @throws IOException if there is any problem reading metadata from the named class * @throws IOException if there is any problem reading metadata from the named class
*/ */
private void collectImports(SourceClass sourceClass, Set<SourceClass> imports, private void collectImports(SourceClass sourceClass, Set<SourceClass> imports, Set<SourceClass> visited) throws IOException {
Set<SourceClass> visited) throws IOException {
try { try {
if (visited.add(sourceClass)) { if (visited.add(sourceClass)) {
for (SourceClass annotation : sourceClass.getAnnotations()) { for (SourceClass annotation : sourceClass.getAnnotations()) {
@ -392,9 +386,9 @@ class ConfigurationClassParser {
this.deferredImportSelectors.clear(); this.deferredImportSelectors.clear();
} }
private void processImports(ConfigurationClass configClass, private void processImports(ConfigurationClass configClass, Collection<SourceClass> sourceClasses, boolean checkForCircularImports)
Collection<SourceClass> sourceClasses, boolean checkForCircularImports)
throws IOException { throws IOException {
if(sourceClasses.isEmpty()) { if(sourceClasses.isEmpty()) {
return; return;
} }
@ -494,8 +488,7 @@ class ConfigurationClassParser {
/** /**
* Factory method to obtain a {@link SourceClass} from a {@link ConfigurationClass}. * Factory method to obtain a {@link SourceClass} from a {@link ConfigurationClass}.
*/ */
public SourceClass asSourceClass(ConfigurationClass configurationClass) public SourceClass asSourceClass(ConfigurationClass configurationClass) throws IOException {
throws IOException {
try { try {
AnnotationMetadata metadata = configurationClass.getMetadata(); AnnotationMetadata metadata = configurationClass.getMetadata();
if (metadata instanceof StandardAnnotationMetadata) { if (metadata instanceof StandardAnnotationMetadata) {
@ -511,8 +504,7 @@ class ConfigurationClassParser {
/** /**
* Factory method to obtain a {@link SourceClass} from a {@link Class}. * Factory method to obtain a {@link SourceClass} from a {@link Class}.
*/ */
public SourceClass asSourceClass(Class<?> classType) public SourceClass asSourceClass(Class<?> classType) throws IOException, ClassNotFoundException {
throws ClassNotFoundException, IOException {
try { try {
// Sanity test that we can read annotations, if not fall back to ASM // Sanity test that we can read annotations, if not fall back to ASM
classType.getAnnotations(); classType.getAnnotations();
@ -526,10 +518,9 @@ class ConfigurationClassParser {
/** /**
* Factory method to obtain {@link SourceClass}s from class names. * Factory method to obtain {@link SourceClass}s from class names.
*/ */
public Collection<SourceClass> asSourceClasses(String[] classNamess) public Collection<SourceClass> asSourceClasses(String[] classNames) throws IOException, ClassNotFoundException {
throws ClassNotFoundException, IOException {
List<SourceClass> annotatedClasses = new ArrayList<SourceClass>(); List<SourceClass> annotatedClasses = new ArrayList<SourceClass>();
for (String className : classNamess) { for (String className : classNames) {
annotatedClasses.add(asSourceClass(className)); annotatedClasses.add(asSourceClass(className));
} }
return annotatedClasses; return annotatedClasses;
@ -538,12 +529,10 @@ class ConfigurationClassParser {
/** /**
* Factory method to obtain a {@link SourceClass} from a class name. * Factory method to obtain a {@link SourceClass} from a class name.
*/ */
public SourceClass asSourceClass(String className) public SourceClass asSourceClass(String className) throws IOException, ClassNotFoundException {
throws ClassNotFoundException, IOException {
if (className.startsWith("java")) { if (className.startsWith("java")) {
// Never use ASM for core java types // Never use ASM for core java types
return new SourceClass(this.resourceLoader.getClassLoader().loadClass( return new SourceClass(this.resourceLoader.getClassLoader().loadClass( className));
className));
} }
return new SourceClass(this.metadataReaderFactory.getMetadataReader(className)); return new SourceClass(this.metadataReaderFactory.getMetadataReader(className));
} }
@ -642,8 +631,7 @@ class ConfigurationClassParser {
private final AnnotationMetadata metadata; private final AnnotationMetadata metadata;
public SourceClass(Object source) {
private SourceClass(Object source) {
this.source = source; this.source = source;
if (source instanceof Class<?>) { if (source instanceof Class<?>) {
this.metadata = new StandardAnnotationMetadata((Class<?>) source, true); this.metadata = new StandardAnnotationMetadata((Class<?>) source, true);
@ -653,40 +641,42 @@ class ConfigurationClassParser {
} }
} }
public final AnnotationMetadata getMetadata() {
return this.metadata;
}
public Class<?> loadClass() throws ClassNotFoundException { public Class<?> loadClass() throws ClassNotFoundException {
if(source instanceof Class<?>) { if (this.source instanceof Class<?>) {
return (Class<?>) source; return (Class<?>) this.source;
} }
String className = ((MetadataReader) source).getClassMetadata().getClassName(); String className = ((MetadataReader) source).getClassMetadata().getClassName();
return resourceLoader.getClassLoader().loadClass(className); return resourceLoader.getClassLoader().loadClass(className);
} }
public boolean isAssignable(Class<?> clazz) throws IOException { public boolean isAssignable(Class<?> clazz) throws IOException {
if (source instanceof Class) { if (this.source instanceof Class) {
return clazz.isAssignableFrom((Class) source); return clazz.isAssignableFrom((Class) this.source);
} }
return new AssignableTypeFilter(clazz).match((MetadataReader) source, return new AssignableTypeFilter(clazz).match((MetadataReader) this.source, metadataReaderFactory);
metadataReaderFactory);
} }
public ConfigurationClass asConfigClass(ConfigurationClass importedBy) public ConfigurationClass asConfigClass(ConfigurationClass importedBy) throws IOException {
throws IOException {
if (this.source instanceof Class<?>) { if (this.source instanceof Class<?>) {
return new ConfigurationClass((Class<?>) this.source, importedBy); return new ConfigurationClass((Class<?>) this.source, importedBy);
} }
return new ConfigurationClass((MetadataReader) source, importedBy); return new ConfigurationClass((MetadataReader) this.source, importedBy);
} }
public Collection<SourceClass> getMemberClasses() throws IOException { public Collection<SourceClass> getMemberClasses() throws IOException {
List<SourceClass> members = new ArrayList<SourceClass>(); List<SourceClass> members = new ArrayList<SourceClass>();
if (source instanceof Class<?>) { if (this.source instanceof Class<?>) {
Class<?> sourceClass = (Class<?>) source; Class<?> sourceClass = (Class<?>) this.source;
for (Class<?> declaredClass : sourceClass.getDeclaredClasses()) { for (Class<?> declaredClass : sourceClass.getDeclaredClasses()) {
try { try {
members.add(asSourceClass(declaredClass)); members.add(asSourceClass(declaredClass));
} }
catch (ClassNotFoundException e) { catch (ClassNotFoundException ex) {
// ignore
} }
} }
} }
@ -696,34 +686,34 @@ class ConfigurationClassParser {
try { try {
members.add(asSourceClass(memberClassName)); members.add(asSourceClass(memberClassName));
} }
catch (ClassNotFoundException e) { catch (ClassNotFoundException ex) {
// ignore
} }
} }
} }
return members; return members;
} }
public SourceClass getSuperClass() throws ClassNotFoundException, IOException { public SourceClass getSuperClass() throws IOException, ClassNotFoundException {
if (source instanceof Class<?>) { if (this.source instanceof Class<?>) {
return asSourceClass(((Class<?>) source).getSuperclass()); return asSourceClass(((Class<?>) this.source).getSuperclass());
} }
return asSourceClass(((MetadataReader) source).getClassMetadata().getSuperClassName()); return asSourceClass(((MetadataReader) this.source).getClassMetadata().getSuperClassName());
} }
public Set<SourceClass> getAnnotations() throws ClassNotFoundException, IOException { public Set<SourceClass> getAnnotations() throws IOException, ClassNotFoundException {
Set<SourceClass> annotations = new LinkedHashSet<SourceClass>(); Set<SourceClass> annotations = new LinkedHashSet<SourceClass>();
for(String annotation : getMetadata().getAnnotationTypes()) { for (String annotation : this.metadata.getAnnotationTypes()) {
annotations.add(getRelated(annotation)); annotations.add(getRelated(annotation));
} }
return annotations; return annotations;
} }
public Collection<SourceClass> getAnnotationAttributes(String annotationType, public Collection<SourceClass> getAnnotationAttributes(String annotationType, String attribute)
String attribute) throws ClassNotFoundException, IOException { throws IOException, ClassNotFoundException {
Map<String, Object> annotationAttributes = getMetadata().getAnnotationAttributes(
annotationType, true); Map<String, Object> annotationAttributes = this.metadata.getAnnotationAttributes(annotationType, true);
if (annotationAttributes == null if (annotationAttributes == null || !annotationAttributes.containsKey(attribute)) {
|| !annotationAttributes.containsKey(attribute)) {
return Collections.emptySet(); return Collections.emptySet();
} }
String[] classNames = (String[]) annotationAttributes.get(attribute); String[] classNames = (String[]) annotationAttributes.get(attribute);
@ -734,45 +724,33 @@ class ConfigurationClassParser {
return rtn; return rtn;
} }
private SourceClass getRelated(String className) throws IOException, private SourceClass getRelated(String className) throws IOException, ClassNotFoundException {
ClassNotFoundException { if (this.source instanceof Class<?>) {
if (source instanceof Class<?>) {
try { try {
Class<?> clazz = resourceLoader.getClassLoader().loadClass(className); Class<?> clazz = resourceLoader.getClassLoader().loadClass(className);
return asSourceClass(clazz); return asSourceClass(clazz);
} }
catch (ClassNotFoundException ex) { catch (ClassNotFoundException ex) {
// ignore
} }
} }
return asSourceClass(className); return asSourceClass(className);
} }
public AnnotationMetadata getMetadata() { @Override
return this.metadata; public boolean equals(Object other) {
return (this == other || (other instanceof SourceClass &&
this.metadata.getClassName().equals(((SourceClass) other).metadata.getClassName())));
} }
@Override @Override
public int hashCode() { public int hashCode() {
return toString().hashCode(); return this.metadata.getClassName().hashCode();
}
@Override
public boolean equals(Object obj) {
if (obj == this) {
return true;
}
if (obj == null) {
return false;
}
if (obj instanceof SourceClass) {
return toString().equals(obj.toString());
}
return false;
} }
@Override @Override
public String toString() { public String toString() {
return getMetadata().getClassName(); return this.metadata.getClassName();
} }
} }

View File

@ -20,6 +20,7 @@ import java.io.IOException;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.AbstractBeanDefinition; import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.core.Conventions; import org.springframework.core.Conventions;
@ -36,8 +37,6 @@ import org.springframework.core.type.classreading.MetadataReaderFactory;
*/ */
abstract class ConfigurationClassUtils { abstract class ConfigurationClassUtils {
private static final Log logger = LogFactory.getLog(ConfigurationClassUtils.class);
private static final String CONFIGURATION_CLASS_FULL = "full"; private static final String CONFIGURATION_CLASS_FULL = "full";
private static final String CONFIGURATION_CLASS_LITE = "lite"; private static final String CONFIGURATION_CLASS_LITE = "lite";
@ -45,6 +44,8 @@ abstract class ConfigurationClassUtils {
private static final String CONFIGURATION_CLASS_ATTRIBUTE = private static final String CONFIGURATION_CLASS_ATTRIBUTE =
Conventions.getQualifiedAttributeName(ConfigurationClassPostProcessor.class, "configurationClass"); Conventions.getQualifiedAttributeName(ConfigurationClassPostProcessor.class, "configurationClass");
private static final Log logger = LogFactory.getLog(ConfigurationClassUtils.class);
/** /**
* Check whether the given bean definition is a candidate for a configuration class, * Check whether the given bean definition is a candidate for a configuration class,
@ -92,7 +93,7 @@ abstract class ConfigurationClassUtils {
} }
public static boolean isConfigurationCandidate(AnnotationMetadata metadata) { public static boolean isConfigurationCandidate(AnnotationMetadata metadata) {
return isFullConfigurationCandidate(metadata) || isLiteConfigurationCandidate(metadata); return (isFullConfigurationCandidate(metadata) || isLiteConfigurationCandidate(metadata));
} }
public static boolean isFullConfigurationCandidate(AnnotationMetadata metadata) { public static boolean isFullConfigurationCandidate(AnnotationMetadata metadata) {
@ -100,13 +101,10 @@ abstract class ConfigurationClassUtils {
} }
public static boolean isLiteConfigurationCandidate(AnnotationMetadata metadata) { public static boolean isLiteConfigurationCandidate(AnnotationMetadata metadata) {
if(metadata.isInterface()) { // Do not consider an interface or an annotation...
return false; // do not consider an interface or an annotation return (!metadata.isInterface() && (
metadata.isAnnotated(Import.class.getName()) || metadata.hasAnnotatedMethods(Bean.class.getName())));
} }
return metadata.isAnnotated(Import.class.getName()) ||
metadata.hasAnnotatedMethods(Bean.class.getName());
}
/** /**
* Determine whether the given bean definition indicates a full @Configuration class. * Determine whether the given bean definition indicates a full @Configuration class.