Optimized ImportAware processing to avoid re-reading class files

(cherry picked from commit 519f78c)
This commit is contained in:
Juergen Hoeller
2013-12-02 16:10:34 +01:00
parent 73a8a1b966
commit c1b772cd9c
2 changed files with 14 additions and 26 deletions

View File

@@ -397,7 +397,7 @@ class ConfigurationClassParser {
}
else {
// candidate class not an ImportSelector or ImportBeanDefinitionRegistrar -> process it as a @Configuration class
this.importStack.registerImport(importingClassMetadata.getClassName(),
this.importStack.registerImport(importingClassMetadata,
(candidate instanceof Class ? ((Class) candidate).getName() : (String) candidate));
processConfigurationClass(candidateToCheck instanceof Class ? new ConfigurationClass((Class) candidateToCheck, true) :
new ConfigurationClass((MetadataReader) candidateToCheck, true));
@@ -469,20 +469,20 @@ class ConfigurationClassParser {
interface ImportRegistry {
String getImportingClassFor(String importedClass);
AnnotationMetadata getImportingClassFor(String importedClass);
}
@SuppressWarnings("serial")
private static class ImportStack extends Stack<ConfigurationClass> implements ImportRegistry {
private final Map<String, String> imports = new HashMap<String, String>();
private final Map<String, AnnotationMetadata> imports = new HashMap<String, AnnotationMetadata>();
public void registerImport(String importingClass, String importedClass) {
public void registerImport(AnnotationMetadata importingClass, String importedClass) {
this.imports.put(importedClass, importingClass);
}
public String getImportingClassFor(String importedClass) {
public AnnotationMetadata getImportingClassFor(String importedClass) {
return this.imports.get(importedClass);
}

View File

@@ -60,7 +60,6 @@ import org.springframework.core.io.ResourceLoader;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
import org.springframework.core.type.classreading.MetadataReaderFactory;
import org.springframework.core.type.classreading.SimpleMetadataReaderFactory;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
@@ -236,8 +235,8 @@ public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPo
throw new IllegalStateException(
"postProcessBeanFactory already called for this post-processor against " + beanFactory);
}
this.factoriesPostProcessed.add((factoryId));
if (!this.registriesPostProcessed.contains((factoryId))) {
this.factoriesPostProcessed.add(factoryId);
if (!this.registriesPostProcessed.contains(factoryId)) {
// BeanDefinitionRegistryPostProcessor hook apparently not supported...
// Simply call processConfigurationClasses lazily at this point then.
processConfigBeanDefinitions((BeanDefinitionRegistry) beanFactory);
@@ -372,36 +371,25 @@ public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPo
}
private static class ImportAwareBeanPostProcessor implements BeanPostProcessor, PriorityOrdered, BeanFactoryAware {
private static class ImportAwareBeanPostProcessor implements BeanPostProcessor, BeanFactoryAware, PriorityOrdered {
private BeanFactory beanFactory;
public void setBeanFactory(BeanFactory beanFactory) {
this.beanFactory = beanFactory;
}
public int getOrder() {
return Ordered.HIGHEST_PRECEDENCE;
}
@Override
public void setBeanFactory(BeanFactory beanFactory) {
this.beanFactory = beanFactory;
}
public Object postProcessBeforeInitialization(Object bean, String beanName) {
if (bean instanceof ImportAware) {
ImportRegistry importRegistry = this.beanFactory.getBean(IMPORT_REGISTRY_BEAN_NAME, ImportRegistry.class);
String importingClass = importRegistry.getImportingClassFor(bean.getClass().getSuperclass().getName());
AnnotationMetadata importingClass = importRegistry.getImportingClassFor(bean.getClass().getSuperclass().getName());
if (importingClass != null) {
try {
AnnotationMetadata metadata =
new SimpleMetadataReaderFactory().getMetadataReader(importingClass).getAnnotationMetadata();
((ImportAware) bean).setImportMetadata(metadata);
}
catch (IOException ex) {
// should never occur -> at this point we know the class is present anyway
throw new IllegalStateException(ex);
}
}
else {
// no importing class was found
((ImportAware) bean).setImportMetadata(importingClass);
}
}
return bean;