前言

PS: 可以先看这个博客了解下Spring Import 三种用法与源码解读

解析

ConfigurationClassParser的processImports方法是最核心的方法

	// 这里是从SourceClass获得imports注解,注意jdk8允许标记多个注解,一个class可以标记多个不同注解,其他注解上也可以标记imports注解,所以需要一个set存放
	private Set<SourceClass> getImports(SourceClass sourceClass) throws IOException {
		Set<SourceClass> imports = new LinkedHashSet<>();
		Set<SourceClass> visited = new LinkedHashSet<>();
		collectImports(sourceClass, imports, visited);
		return imports;
	}

	private void processImports(ConfigurationClass configClass, SourceClass currentSourceClass,Collection<SourceClass> importCandidates,boolean checkForCircularImports) throws IOException {

		if (importCandidates.isEmpty()) {
			return;
		}

		if (checkForCircularImports &amp;&amp;
this.importStack.contains(configClass)) {
			this.problemReporter.error(new CircularImportProblem(configClass,
this.importStack));
		}
		else {
			this.importStack.push(configClass);
			try {
				for (SourceClass candidate : importCandidates) {
					// 看注解里面的类是不是ImportSelector的实现类
					if (candidate.isAssignable(ImportSelector.class)) {
						Class<?> candidateClass = candidate.loadClass();
						ImportSelector selector = BeanUtils.instantiateClass(candidateClass, ImportSelector.class);
						invokeAwareMethods(selector);
						// 判断是否是需要延迟加载,继承DeferredImportSelector类的都会延迟加载
						if (this.deferredImportSelectors != null &amp;&amp; selector instanceof DeferredImportSelector) {
							this.deferredImportSelectors.add(new DeferredImportSelectorHolder(configClass, (DeferredImportSelector) selector));
						}
						else {
							// 执行ImportSelector的实现类,返回需要加载的内容
							String[] importClassNames = selector.selectImports(currentSourceClass.getMetadata());
							Collection<SourceClass> importSourceClasses = asSourceClasses(importClassNames);
							processImports(configClass, currentSourceClass, importSourceClasses, false);
						}
					}
					else if (candidate.isAssignable(ImportBeanDefinitionRegistrar.class)) {
						// 这个是非常重要的,ImportBeanDefinitionRegistrar.addImportBeanDefinitionRegistrar方法的形参是registrar。
						Class<?> candidateClass = candidate.loadClass();
						ImportBeanDefinitionRegistrar registrar =BeanUtils.instantiateClass(candidateClass,ImportBeanDefinitionRegistrar.class);
						invokeAwareMethods(registrar);
						configClass.addImportBeanDefinitionRegistrar(registrar,
currentSourceClass.getMetadata());
					}
					else {
						//
如果都不是,就调动processConfigurationClass(迭代了,processImports上两级的调用就是
processConfigurationClass)
						this.importStack.registerImport(currentSourceClass.getMetadata(), candidate.getMetadata().getClassName());
						processConfigurationClass(candidate.asConfigClass(configClass));
					}
				}
			}
			catch (BeanDefinitionStoreException ex) {
				throw ex;
			}
			catch (Exception ex) {
				throw new BeanDefinitionStoreException("Failed to process import candidates for configuration class [" +configClass.getMetadata().getClassName() + "]", ex);
			}
			finally {
				this.importStack.pop();
			}
		}
	}

重点

ImportSelector
public interface ImportSelector {
	String[] selectImports(AnnotationMetadata importingClassMetadata);
}


String[] importClassNames = selector.selectImports(currentSourceClass.getMetadata());
Collection&lt;SourceClass&gt; importSourceClasses = asSourceClasses(importClassNames);
processImports(configClass, currentSourceClass, importSourceClasses, false);
ImportBeanDefinitionRegistrar
public interface ImportBeanDefinitionRegistrar {
	public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry);
}

public static class BeanPostProcessorsRegistrar implements ImportBeanDefinitionRegistrar, BeanFactoryAware {

		private ConfigurableListableBeanFactory beanFactory;

		@Override
		public void setBeanFactory(BeanFactory beanFactory) throws
BeansException {
			if (beanFactory instanceof ConfigurableListableBeanFactory) {
				this.beanFactory = (ConfigurableListableBeanFactory) beanFactory;
			}
		}

public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata,BeanDefinitionRegistry registry) {
	if (this.beanFactory == null) {
				return;
	}
			 registerSyntheticBeanIfMissing(registry,"webServerFactoryCustomizerBeanPostProcessor",WebServerFactoryCustomizerBeanPostProcessor.class);
			registerSyntheticBeanIfMissing(registry,"errorPageRegistrarBeanPostProcessor",ErrorPageRegistrarBeanPostProcessor.class);
		}

		private void registerSyntheticBeanIfMissing(BeanDefinitionRegistry registry,String name, Class&lt;?&gt; beanClass) {
			if (ObjectUtils.isEmpty(this.beanFactory.getBeanNamesForType(beanClass, true, false))) {
				RootBeanDefinition beanDefinition = new RootBeanDefinition(beanClass);
				beanDefinition.setSynthetic(true);
				registry.registerBeanDefinition(name, beanDefinition);
			}
		}

	}

ImportBeanDefinitionRegistrar registrar = BeanUtils.instantiateClass(candidateClass,
ImportBeanDefinitionRegistrar.class);
invokeAwareMethods(registrar);
configClass.addImportBeanDefinitionRegistrar(registrar, currentSourceClass.getMetadata());

public void  addImportBeanDefinitionRegistrar(ImportBeanDefinitionRegistrar registrar, AnnotationMetadata importingClassMetadata) {
		this.importBeanDefinitionRegistrars.put(registrar, importingClassMetadata);
}

执行时机,是等待所以初始化的注解或者class解析完成第五章 spring-connet之Imports注解来龙去脉-LMLPHP

只有一次出发机会
@SpringBootApplication
public class UserConsumeApplication {

    public static void main(String[] args) {
        SpringApplication.run(UserConsumeApplication.class, args);
    }
}

#######

坐在一个很小的公园的花坛上写完。

09-22 13:54