beanPostProcessor,这是在每个bean陷入初始化时会调用的。
BeanDefinitionRegistryPostProcessor,这是beanFactoryProcessor的子类,它的存在意义在于真正执行beanFactoryProcessor之前注册进入更多的bean,包括beanFactoryProcessor这种bean。这点我们可以从它的专用待实现方法postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry)中看出,它传入了注册中心,这样我们就可以把新的beanDefinition直接注册进去了。
对于BeanDefinitionRegistryPostProcessor而言,如果是一开始就加入List 的话,那会最优先执行,在此之后,会分别以PriorityOrdered,Ordered,其余顺序执行。由于ConfigurationClassPostProcessor属于PriorityOrdered,所以如果通过@Component注入的BeanDefinitionRegistryPostProcessor设置为PriorityOrdered是无效的。
beanFactoryProcessor,这是工厂执行的后置处理器,在开始bean的创建前,会调用完所有beanFactoryProcessor和BeanDefinitionRegistryPostProcessor的后置处理方法postProcessBeanFactory()。在refresh方法中,先完成beanFactoryProcessor和BeanDefinitionRegistryPostProcessor的调用,然后完成beanPostProcessor的bean初始化,然后最后才会到达其它bean的初始化。
// 空实现
postProcessBeanFactory(beanFactory);// 完成beanFactoryProcessor和BeanDefinitionRegistryPostProcessor的调用
invokeBeanFactoryPostProcessors(beanFactory);// 在beanDefinition中找到所有BeanPostProcessor,完成getBean()并且往beanPostProcessors加入
registerBeanPostProcessors(beanFactory);.........................................................// bean的真正创建
finishBeanFactoryInitialization(beanFactory);
public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, List beanFactoryPostProcessors) {// 这个集合用来承装所有执行过并且会生成beanDefinition的BeanDefinitionRegistry,这是在后续调用所有BeanFactoryPostProcessorSet processedBeans = new HashSet<>();// AnnotationConfigApplicationContext就是BeanDefinitionRegistry的实现,所以一定进入if (beanFactory instanceof BeanDefinitionRegistry) {BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;List regularPostProcessors = new ArrayList<>();List registryProcessors = new ArrayList<>();// 如果是BeanDefinitionRegistryPostProcessor,那么调用并加入集合,否则就是BeanFactoryPostProcessor,先不调用,加入集合,等到后续集中调用for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {BeanDefinitionRegistryPostProcessor registryProcessor =(BeanDefinitionRegistryPostProcessor) postProcessor;registryProcessor.postProcessBeanDefinitionRegistry(registry);registryProcessors.add(registryProcessor);}else {regularPostProcessors.add(postProcessor);}}// 这个列表是用来承装这一次BeanDefinitionRegistryPostProcessorList currentRegistryProcessors = new ArrayList<>();// 将所有最高优先级处理器拿出来,挨个执行,并放入processedBeansString[] postProcessorNames =beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);for (String ppName : postProcessorNames) {if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));processedBeans.add(ppName);}}sortPostProcessors(currentRegistryProcessors, beanFactory);registryProcessors.addAll(currentRegistryProcessors);invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);currentRegistryProcessors.clear();// 将所有优先级处理器拿出来,挨个执行,并放入processedBeanspostProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);for (String ppName : postProcessorNames) {if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));processedBeans.add(ppName);}}sortPostProcessors(currentRegistryProcessors, beanFactory);registryProcessors.addAll(currentRegistryProcessors);invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);currentRegistryProcessors.clear();// 一直执行所有BeanDefinitionRegistryPostProcessor,直到所有都进入了processedBeansboolean reiterate = true;while (reiterate) {reiterate = false;postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);for (String ppName : postProcessorNames) {if (!processedBeans.contains(ppName)) {currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));processedBeans.add(ppName);reiterate = true;}}sortPostProcessors(currentRegistryProcessors, beanFactory);registryProcessors.addAll(currentRegistryProcessors);invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);currentRegistryProcessors.clear();}// 可以看成将所有processedBeans加上beanFactoryPostProcessors的所有后置处理器共同执行了该方法invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);}else {// Invoke factory processors registered with the context instance.invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);}...
}
以下逻辑就明确了,将所有BeanFactoryPostProcessor取出来,除了processedBean中那些后置处理器,其余的全部执行一遍
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the bean factory post-processors apply to them!
String[] postProcessorNames =beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);// Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
List priorityOrderedPostProcessors = new ArrayList<>();
List orderedPostProcessorNames = new ArrayList<>();
List nonOrderedPostProcessorNames = new ArrayList<>();
for (String ppName : postProcessorNames) {if (processedBeans.contains(ppName)) {// skip - already processed in first phase above}else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));}else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {orderedPostProcessorNames.add(ppName);}else {nonOrderedPostProcessorNames.add(ppName);}
}// First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);// Next, invoke the BeanFactoryPostProcessors that implement Ordered.
List orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
for (String postProcessorName : orderedPostProcessorNames) {orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
sortPostProcessors(orderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);// Finally, invoke all other BeanFactoryPostProcessors.
List nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
for (String postProcessorName : nonOrderedPostProcessorNames) {nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);// Clear cached merged bean definitions since the post-processors might have
// modified the original metadata, e.g. replacing placeholders in values...
beanFactory.clearMetadataCache();
我们可以简要把源码分为三部分
1 识别所有config
2 解析所有config
3 将解析结果全部加入BeanDefinition,重复2 3 步骤
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {List configCandidates = new ArrayList<>();String[] candidateNames = registry.getBeanDefinitionNames();// 把所有拥有@Configuration的beanDefinition加入for (String beanName : candidateNames) {BeanDefinition beanDef = registry.getBeanDefinition(beanName);if (beanDef.getAttribute(ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE) != null) {if (logger.isDebugEnabled()) {logger.debug("Bean definition has already been processed as a configuration class: " + beanDef);}}else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));}}// 如果没有if (configCandidates.isEmpty()) {return;}// 给筛选过的beanDefinition的排序configCandidates.sort((bd1, bd2) -> {int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition());int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition());return Integer.compare(i1, i2);});// Detect any custom bean name generation strategy supplied through the enclosing application contextSingletonBeanRegistry sbr = null;if (registry instanceof SingletonBeanRegistry) {sbr = (SingletonBeanRegistry) registry;if (!this.localBeanNameGeneratorSet) {BeanNameGenerator generator = (BeanNameGenerator) sbr.getSingleton(AnnotationConfigUtils.CONFIGURATION_BEAN_NAME_GENERATOR);if (generator != null) {this.componentScanBeanNameGenerator = generator;this.importBeanNameGenerator = generator;}}}if (this.environment == null) {this.environment = new StandardEnvironment();}// Parse each @Configuration classConfigurationClassParser parser = new ConfigurationClassParser(this.metadataReaderFactory, this.problemReporter, this.environment,this.resourceLoader, this.componentScanBeanNameGenerator, registry);Set candidates = new LinkedHashSet<>(configCandidates);Set alreadyParsed = new HashSet<>(configCandidates.size());do {// 正式处理按照@Configuration逻辑处理parser.parse(candidates);parser.validate();Set configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());configClasses.removeAll(alreadyParsed);if (this.reader == null) {this.reader = new ConfigurationClassBeanDefinitionReader(registry, this.sourceExtractor, this.resourceLoader, this.environment,this.importBeanNameGenerator, parser.getImportRegistry());}// 对于剩下的@bean,@importResource和importBeanDefinitionRegistrar进行统一生成beanDefinition并注册注入// 并且@import直接指向的普通类一直没有注册成beanDefinition,这里也会完成this.reader.loadBeanDefinitions(configClasses);// alreadyParsed添加所有执行过的configalreadyParsed.addAll(configClasses);candidates.clear();// 对所有beanDefinition进行处理,将没parse过的config再次加入候选者,进行处理,其实也就是70行的那三种beanDefinitionif (registry.getBeanDefinitionCount() > candidateNames.length) {String[] newCandidateNames = registry.getBeanDefinitionNames();Set oldCandidateNames = new HashSet<>(Arrays.asList(candidateNames));Set alreadyParsedClasses = new HashSet<>();for (ConfigurationClass configurationClass : alreadyParsed) {alreadyParsedClasses.add(configurationClass.getMetadata().getClassName());}for (String candidateName : newCandidateNames) {if (!oldCandidateNames.contains(candidateName)) {BeanDefinition bd = registry.getBeanDefinition(candidateName);if (ConfigurationClassUtils.checkConfigurationClassCandidate(bd, this.metadataReaderFactory) &&!alreadyParsedClasses.contains(bd.getBeanClassName())) {candidates.add(new BeanDefinitionHolder(bd, candidateName));}}}candidateNames = newCandidateNames;}}while (!candidates.isEmpty());// Register the ImportRegistry as a bean in order to support ImportAware @Configuration classesif (sbr != null && !sbr.containsSingleton(IMPORT_REGISTRY_BEAN_NAME)) {sbr.registerSingleton(IMPORT_REGISTRY_BEAN_NAME, parser.getImportRegistry());}if (this.metadataReaderFactory instanceof CachingMetadataReaderFactory) {// Clear cache in externally provided MetadataReaderFactory; this is a no-op// for a shared cache since it'll be cleared by the ApplicationContext.((CachingMetadataReaderFactory) this.metadataReaderFactory).clearCache();}
}
postProcessBeanFactory无非是一个增强器,作用就是为了非轻量的Configuration在@bean方法反复调用时返回的是同一个对象。
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {// 没用的int factoryId = System.identityHashCode(beanFactory);if (this.factoriesPostProcessed.contains(factoryId)) {throw new IllegalStateException("postProcessBeanFactory already called on this post-processor against " + beanFactory);}// 都添加了,压根不调用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);}// 做了一下增强,然后加了个后置处理器enhanceConfigurationClasses(beanFactory);beanFactory.addBeanPostProcessor(new ImportAwareBeanPostProcessor(beanFactory));
}public void enhanceConfigurationClasses(ConfigurableListableBeanFactory beanFactory) {Map configBeanDefs = new LinkedHashMap<>();for (String beanName : beanFactory.getBeanDefinitionNames()) {BeanDefinition beanDef = beanFactory.getBeanDefinition(beanName);Object configClassAttr = beanDef.getAttribute(ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE);..........................//可以看出,如果不是FULL,那么configBeanDefs就不会有值,不会有值,就会在isEmpty()return,减少了CGLIB增强if (ConfigurationClassUtils.CONFIGURATION_CLASS_FULL.equals(configClassAttr)) {if (!(beanDef instanceof AbstractBeanDefinition)) {throw new BeanDefinitionStoreException("Cannot enhance @Configuration bean definition '" +beanName + "' since it is not stored in an AbstractBeanDefinition subclass");}else if (logger.isInfoEnabled() && beanFactory.containsSingleton(beanName)) {logger.info("Cannot enhance @Configuration bean definition '" + beanName +"' since its singleton instance has been created too early. The typical cause " +"is a non-static @Bean method with a BeanDefinitionRegistryPostProcessor " +"return type: Consider declaring such methods as 'static'.");}configBeanDefs.put(beanName, (AbstractBeanDefinition) beanDef);}}if (configBeanDefs.isEmpty()) {// nothing to enhance -> return immediatelyreturn;}ConfigurationClassEnhancer enhancer = new ConfigurationClassEnhancer();for (Map.Entry entry : configBeanDefs.entrySet()) {AbstractBeanDefinition beanDef = entry.getValue();// If a @Configuration class gets proxied, always proxy the target classbeanDef.setAttribute(AutoProxyUtils.PRESERVE_TARGET_CLASS_ATTRIBUTE, Boolean.TRUE);// Set enhanced subclass of the user-specified bean classClass> configClass = beanDef.getBeanClass();Class> enhancedClass = enhancer.enhance(configClass, this.beanClassLoader);if (configClass != enhancedClass) {if (logger.isTraceEnabled()) {logger.trace(String.format("Replacing bean definition '%s' existing class '%s' with " +"enhanced class '%s'", entry.getKey(), configClass.getName(), enhancedClass.getName()));}beanDef.setBeanClass(enhancedClass);}}
}
就是满足条件ConfigurationClassUtils.checkConfigurationClassCandidate(…)
也就是满足拥有@Configuration,@Component,@ComponentScan,@Import,@ImportResource其中之一
对于Configuration而言,分为轻量级和非轻量,是通过@Configuration下的属性proxyBeanMethods来判断的,如果是true,那么是非轻量,每次调用getBean()返回单例对象,如果是false,那么是轻量,每次调用new方法返回新的对象。
调用getBean主要是在它的postProcessBeanFactory的增强方法enhanceConfigurationClasses()执行
public @interface Configuration {@AliasFor(annotation = Component.class)String value() default "";boolean proxyBeanMethods() default true;}
以下代码主要干两件事,取出元数据,判断是否是Configuration,无论是轻量还是非轻量
public static boolean checkConfigurationClassCandidate(BeanDefinition beanDef, MetadataReaderFactory metadataReaderFactory) {// 取出元数据String className = beanDef.getBeanClassName();if (className == null || beanDef.getFactoryMethodName() != null) {return false;}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();if (BeanFactoryPostProcessor.class.isAssignableFrom(beanClass) ||BeanPostProcessor.class.isAssignableFrom(beanClass) ||AopInfrastructureBean.class.isAssignableFrom(beanClass) ||EventListenerFactory.class.isAssignableFrom(beanClass)) {return false;}metadata = AnnotationMetadata.introspect(beanClass);}else {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;}}// 分为轻量和非轻量Configuration,只有这两种可以进入Map config = metadata.getAnnotationAttributes(Configuration.class.getName());// 如果是ProxyBeans为true,说明是非轻量if (config != null && !Boolean.FALSE.equals(config.get("proxyBeanMethods"))) {beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_FULL);}// 如果不是@Configuration,那么看看是不是@Component,@ComponentScan,@Import,@ImportResource其中之一else if (config != null || isConfigurationCandidate(metadata)) {beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_LITE);}else {return false;}// 用于下一步Configuration排序使用Integer order = getOrder(metadata);if (order != null) {beanDef.setAttribute(ORDER_ATTRIBUTE, order);}return true;
}
protected void processConfigurationClass(ConfigurationClass configClass, Predicate filter) throws IOException {if (this.conditionEvaluator.shouldSkip(configClass.getMetadata(), ConfigurationPhase.PARSE_CONFIGURATION)) {return;}ConfigurationClass existingClass = this.configurationClasses.get(configClass);if (existingClass != null) {// 说明要不就是@Component内部类,要不就是@Import指向的类,都不需要再次执行了if (configClass.isImported()) {// 如果当前有更多import数据,更新进去if (existingClass.isImported()) {existingClass.mergeImportedBy(configClass);}// Otherwise ignore new imported config class; existing non-imported class overrides it.return;}else {// Explicit bean definition found, probably replacing an import.// Let's remove the old one and go with the new one.this.configurationClasses.remove(configClass);this.knownSuperclasses.values().removeIf(configClass::equals);}}// 这一行是生成一个类的加载工具,只需要调用sourceClass.loadClass()就可以获得Config的classSourceClass sourceClass = asSourceClass(configClass, filter);do {sourceClass = doProcessConfigurationClass(configClass, sourceClass, filter);}while (sourceClass != null);this.configurationClasses.put(configClass, configClass);
}
protected final SourceClass doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass, Predicate filter)throws IOException {if (configClass.getMetadata().isAnnotated(Component.class.getName())) {// 解析存在内部类注释@Component的情况processMemberClasses(configClass, sourceClass, filter);}// 直接将@propertySource注解对应的.properties文件内容注册到environment的MutablePropertiesfor (AnnotationAttributes propertySource : AnnotationConfigUtils.attributesForRepeatable(sourceClass.getMetadata(), PropertySources.class,org.springframework.context.annotation.PropertySource.class)) {if (this.environment instanceof ConfigurableEnvironment) {processPropertySource(propertySource);}else {logger.info("Ignoring @PropertySource annotation on [" + sourceClass.getMetadata().getClassName() +"]. Reason: Environment must implement ConfigurableEnvironment");}}// 处理@ComponentScan注解Set componentScans = AnnotationConfigUtils.attributesForRepeatable(sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class);if (!componentScans.isEmpty() &&!this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) {for (AnnotationAttributes componentScan : componentScans) {// 往内层翻,会发现其实也是对对应路径进行所有类是否有@Component的判断// 这和第一篇文章,spring工厂流程中,scanner的处理有异曲同工之妙,都是利用了ClassPathScanningCandidateComponentProviderSet scannedBeanDefinitions =this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());// 如果发现这个beanDefinition又再次符合config的情况,让它重新执行parser.parse// 这里并不需要beanDefinition的注册了,因为在上面的componentScanParser.parse已经完成了for (BeanDefinitionHolder holder : scannedBeanDefinitions) {BeanDefinition bdCand = holder.getBeanDefinition().getOriginatingBeanDefinition();if (bdCand == null) {bdCand = holder.getBeanDefinition();}if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) {parse(bdCand.getBeanClassName(), holder.getBeanName());}}}}// getImports的用处是将这个类的注解进行递归识别,将所有@import注解都给提取出来// 在这个方法中,会对@Import,@ImportSelector,ImportBeanDefinitionRegistrar进行解析和注册processImports(configClass, sourceClass, getImports(sourceClass), filter, true);// Process any @ImportResource annotationsAnnotationAttributes importResource =AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class);if (importResource != null) {String[] resources = importResource.getStringArray("locations");Class extends BeanDefinitionReader> readerClass = importResource.getClass("reader");for (String resource : resources) {String resolvedResource = this.environment.resolveRequiredPlaceholders(resource);configClass.addImportedResource(resolvedResource, readerClass);}}// 把所有bean方法取出,加到configclassSet beanMethods = retrieveBeanMethodMetadata(sourceClass);for (MethodMetadata methodMetadata : beanMethods) {configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));}// 把自己所有接口的bean方法也取出,加到configclassprocessInterfaces(configClass, sourceClass);// 如果存在父类,那么就返回父类,这样父类就会执行doProcessConfigurationClassif (sourceClass.getMetadata().hasSuperClass()) {String superclass = sourceClass.getMetadata().getSuperClassName();if (superclass != null && !superclass.startsWith("java") &&!this.knownSuperclasses.containsKey(superclass)) {this.knownSuperclasses.put(superclass, configClass);// Superclass found, return its annotation metadata and recursereturn sourceClass.getSuperClass();}}// 完全结束return null;
}
private void collectImports(SourceClass sourceClass, Set imports, Set visited)throws IOException {if (visited.add(sourceClass)) {for (SourceClass annotation : sourceClass.getAnnotations()) {String annName = annotation.getMetadata().getClassName();if (!annName.equals(Import.class.getName())) {collectImports(annotation, imports, visited);}}imports.addAll(sourceClass.getAnnotationAttributes(Import.class.getName(), "value"));}
}
private void processImports(ConfigurationClass configClass, SourceClass currentSourceClass,Collection importCandidates, Predicate exclusionFilter,boolean checkForCircularImports) {if (importCandidates.isEmpty()) {return;}if (checkForCircularImports && isChainedImportOnStack(configClass)) {this.problemReporter.error(new CircularImportProblem(configClass, this.importStack));}else {this.importStack.push(configClass);try {for (SourceClass candidate : importCandidates) {// 如果import指向的是selectorif (candidate.isAssignable(ImportSelector.class)) {// Candidate class is an ImportSelector -> delegate to it to determine importsClass> candidateClass = candidate.loadClass();ImportSelector selector = ParserStrategyUtils.instantiateClass(candidateClass, ImportSelector.class,this.environment, this.resourceLoader, this.registry);Predicate selectorFilter = selector.getExclusionFilter();if (selectorFilter != null) {exclusionFilter = exclusionFilter.or(selectorFilter);}if (selector instanceof DeferredImportSelector) {this.deferredImportSelectorHandler.handle(configClass, (DeferredImportSelector) selector);}else {// 直接取出importselector的返回字符串,然后拿去递归调用 String[] importClassNames = selector.selectImports(currentSourceClass.getMetadata());Collection importSourceClasses = asSourceClasses(importClassNames, exclusionFilter);processImports(configClass, currentSourceClass, importSourceClasses, exclusionFilter, false);}}// 如果import指向的是ImportBeanDefinitionRegistrar,会加到configclass当中去,等待后续处理else if (candidate.isAssignable(ImportBeanDefinitionRegistrar.class)) {// Candidate class is an ImportBeanDefinitionRegistrar ->// delegate to it to register additional bean definitionsClass> candidateClass = candidate.loadClass();ImportBeanDefinitionRegistrar registrar =ParserStrategyUtils.instantiateClass(candidateClass, ImportBeanDefinitionRegistrar.class,this.environment, this.resourceLoader, this.registry);configClass.addImportBeanDefinitionRegistrar(registrar, currentSourceClass.getMetadata());}// 如果import指向的是普通类,当作config类递归使用parser处理else {// Candidate class not an ImportSelector or ImportBeanDefinitionRegistrar ->// process it as an @Configuration classthis.importStack.registerImport(currentSourceClass.getMetadata(), candidate.getMetadata().getClassName());processConfigurationClass(candidate.asConfigClass(configClass), exclusionFilter);}}}catch (BeanDefinitionStoreException ex) {throw ex;}catch (Throwable ex) {throw new BeanDefinitionStoreException("Failed to process import candidates for configuration class [" +configClass.getMetadata().getClassName() + "]", ex);}finally {this.importStack.pop();}}
}