diff --git a/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClass.java b/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClass.java index 5087c1fd2c3..1fc5c91d79f 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClass.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClass.java @@ -68,11 +68,10 @@ final class ConfigurationClass { * Create a new {@link ConfigurationClass} with the given name. * @param metadataReader reader used to parse the underlying {@link Class} * @param beanName must not be {@code null} - * @throws IllegalArgumentException if beanName is null (as of Spring 3.1.1) * @see ConfigurationClass#ConfigurationClass(Class, ConfigurationClass) */ public ConfigurationClass(MetadataReader metadataReader, String beanName) { - Assert.hasText(beanName, "bean name must not be null"); + Assert.hasText(beanName, "Bean name must not be null"); this.metadata = metadataReader.getAnnotationMetadata(); this.resource = metadataReader.getResource(); this.beanName = beanName; @@ -96,7 +95,6 @@ final class ConfigurationClass { * Create a new {@link ConfigurationClass} with the given name. * @param clazz the underlying {@link Class} to represent * @param beanName name of the {@code @Configuration} class bean - * @throws IllegalArgumentException if beanName is null (as of Spring 3.1.1) * @see ConfigurationClass#ConfigurationClass(Class, ConfigurationClass) */ public ConfigurationClass(Class clazz, String beanName) { @@ -120,6 +118,19 @@ final class ConfigurationClass { this.importedBy.add(importedBy); } + /** + * Create a new {@link ConfigurationClass} with the given name. + * @param metadata the metadata for the underlying class to represent + * @param beanName name of the {@code @Configuration} class bean + * @see ConfigurationClass#ConfigurationClass(Class, ConfigurationClass) + */ + public ConfigurationClass(AnnotationMetadata metadata, String beanName) { + Assert.hasText(beanName, "Bean name must not be null"); + this.metadata = metadata; + this.resource = new DescriptiveResource(metadata.getClassName()); + this.beanName = beanName; + } + public AnnotationMetadata getMetadata() { return this.metadata; diff --git a/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassParser.java b/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassParser.java index 2c2f1569c18..3d64a89ba96 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassParser.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassParser.java @@ -41,6 +41,7 @@ import org.springframework.beans.factory.BeanClassLoaderAware; import org.springframework.beans.factory.BeanDefinitionStoreException; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.BeanFactoryAware; +import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.config.BeanDefinitionHolder; import org.springframework.beans.factory.config.ConfigurableBeanFactory; @@ -158,7 +159,10 @@ class ConfigurationClassParser { for (BeanDefinitionHolder holder : configCandidates) { BeanDefinition bd = holder.getBeanDefinition(); try { - if (bd instanceof AbstractBeanDefinition && ((AbstractBeanDefinition) bd).hasBeanClass()) { + if (bd instanceof AnnotatedBeanDefinition) { + parse(((AnnotatedBeanDefinition) bd).getMetadata(), holder.getBeanName()); + } + else if (bd instanceof AbstractBeanDefinition && ((AbstractBeanDefinition) bd).hasBeanClass()) { parse(((AbstractBeanDefinition) bd).getBeanClass(), holder.getBeanName()); } else { @@ -169,32 +173,26 @@ class ConfigurationClassParser { throw ex; } catch (Exception ex) { - throw new BeanDefinitionStoreException("Failed to parse configuration class [" + bd.getBeanClassName() + "]", ex); + throw new BeanDefinitionStoreException( + "Failed to parse configuration class [" + bd.getBeanClassName() + "]", ex); } } processDeferredImportSelectors(); } - /** - * Parse the specified {@link Configuration @Configuration} class. - * @param className the name of the class to parse - * @param beanName may be null, but if populated represents the bean id - * (assumes that this configuration class was configured via XML) - */ protected final void parse(String className, String beanName) throws IOException { MetadataReader reader = this.metadataReaderFactory.getMetadataReader(className); processConfigurationClass(new ConfigurationClass(reader, beanName)); } - /** - * Parse the specified {@link Configuration @Configuration} class. - * @param clazz the Class to parse - * @param beanName must not be null (as of Spring 3.1.1) - */ protected final void parse(Class clazz, String beanName) throws IOException { processConfigurationClass(new ConfigurationClass(clazz, beanName)); } + protected final void parse(AnnotationMetadata metadata, String beanName) throws IOException { + processConfigurationClass(new ConfigurationClass(metadata, beanName)); + } + protected void processConfigurationClass(ConfigurationClass configClass) throws IOException { if (this.conditionEvaluator.shouldSkip(configClass.getMetadata(), ConfigurationPhase.PARSE_CONFIGURATION)) { diff --git a/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassUtils.java b/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassUtils.java index bfa4c2bbd35..c462fa1fc0e 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassUtils.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassUtils.java @@ -23,6 +23,7 @@ import java.util.Set; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.support.AbstractBeanDefinition; import org.springframework.core.Conventions; @@ -70,41 +71,47 @@ abstract class ConfigurationClassUtils { * @return whether the candidate qualifies as (any kind of) configuration class */ public static boolean checkConfigurationClassCandidate(BeanDefinition beanDef, MetadataReaderFactory metadataReaderFactory) { - AnnotationMetadata metadata = null; + String className = beanDef.getBeanClassName(); + if (className == null) { + return false; + } - // Check already loaded Class if present... - // since we possibly can't even load the class file for this Class. - if (beanDef instanceof AbstractBeanDefinition && ((AbstractBeanDefinition) beanDef).hasBeanClass()) { + AnnotationMetadata metadata; + if (beanDef instanceof AnnotatedBeanDefinition && + className.equals(((AnnotatedBeanDefinition) beanDef).getMetadata().getClassName())) { + // Can reuse the pre-parsed metadata from the given BeanDefinition... + metadata = ((AnnotatedBeanDefinition) beanDef).getMetadata(); + } + else if (beanDef instanceof AbstractBeanDefinition && ((AbstractBeanDefinition) beanDef).hasBeanClass()) { + // Check already loaded Class if present... + // since we possibly can't even load the class file for this Class. Class beanClass = ((AbstractBeanDefinition) beanDef).getBeanClass(); metadata = new StandardAnnotationMetadata(beanClass, true); } else { - String className = beanDef.getBeanClassName(); - if (className != null) { - try { - MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(className); - metadata = metadataReader.getAnnotationMetadata(); - } - catch (IOException ex) { - if (logger.isDebugEnabled()) { - logger.debug("Could not find class file for introspecting factory methods: " + className, ex); - } - return false; + try { + MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(className); + metadata = metadataReader.getAnnotationMetadata(); + } + catch (IOException ex) { + if (logger.isDebugEnabled()) { + logger.debug("Could not find class file for introspecting configuration annotations: " + className, ex); } + return false; } } - if (metadata != null) { - if (isFullConfigurationCandidate(metadata)) { - beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_FULL); - return true; - } - else if (isLiteConfigurationCandidate(metadata)) { - beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_LITE); - return true; - } + if (isFullConfigurationCandidate(metadata)) { + beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_FULL); + return true; + } + else if (isLiteConfigurationCandidate(metadata)) { + beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_LITE); + return true; + } + else { + return false; } - return false; } /**