Spring源码分析refresh()第二篇

invokeBeanFactoryPostProcessors方法

这个方法比较重要 实例化和调用所有已注册的BeanFactoryPostProcessor bean,如果有已经注入的BeanFactoryPostProcessor 则优先调用
进入方法逐步分析:

	protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
	//这里获取的getBeanFactoryPostProcessors()为空 因为没有手动调用addBeanFactoryPostProcessor 添加
	PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
		// Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
		// (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
		if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
			beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
			beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
		}
	}
备注,手动添加后置处理器到beanFactoryPostProcessors
	AnnotationConfigApplicationContext annotationConfigApplicationContext =
				new AnnotationConfigApplicationContext(AppConfig.class);
		annotationConfigApplicationContext.addBeanFactoryPostProcessor(XXX);

具体查看PostProcessorRegistrationDelegate类的 invokeBeanFactoryPostProcessors方法

	public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {

			Set<String> processedBeans = new HashSet<>();
			//beanFactory是DefaultListableBeanFactory,是BeanDefinitionRegistry的实现类,所以肯定满足if
			if (beanFactory instanceof BeanDefinitionRegistry) {
				BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
				//regularPostProcessors 用来存放BeanFactoryPostProcessor,
				List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
				//记录全部注册的 BeanDefinitionRegistryPostProcessor
				List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
				// 循环传进来的beanFactoryPostProcessors,正常情况下,beanFactoryPostProcessors肯定没有数据 因为beanFactoryPostProcessors是获得手动添加的,而不是spring扫描的
				for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
					if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
						//首先处理BeanDefinitionRegistryPostProcessor 因为BeanDefinitionRegistryPostProcessor也扩展了BeanFactoryPostProcessor
						BeanDefinitionRegistryPostProcessor registryProcessor = (BeanDefinitionRegistryPostProcessor) postProcessor;
						registryProcessor.postProcessBeanDefinitionRegistry(registry);
						registryProcessors.add(registryProcessor);
					} else {
						//不是的话,就装到regularPostProcessors
						regularPostProcessors.add(postProcessor);
					}
				}

				//一个临时变量,用来装载BeanDefinitionRegistryPostProcessor
				List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();

				// 获得实现BeanDefinitionRegistryPostProcessor接口的类的BeanName:org.springframework.context.annotation.internalConfigurationAnnotationProcessor
				// 并且装入数组postProcessorNames,我理解一般情况下,只会找到一个
				// 这里又有一个坑,为什么我自己创建了一个实现BeanDefinitionRegistryPostProcessor接口的类,也打上了@Component注解
				// 配置类也加上了@Component注解,但是这里却没有拿到
				// 因为直到这一步,Spring还没有去扫描,扫描是在ConfigurationClassPostProcessor类中完成的,也就是下面的第一个
				// invokeBeanDefinitionRegistryPostProcessors方法
				String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
				for (String ppName : postProcessorNames) {
					if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
						//获得ConfigurationClassPostProcessor类,并且放到currentRegistryProcessors
						//ConfigurationClassPostProcessor是很重要的一个类,它实现了BeanDefinitionRegistryPostProcessor接口
						//BeanDefinitionRegistryPostProcessor接口又实现了BeanFactoryPostProcessor接口
						//ConfigurationClassPostProcessor是极其重要的类
						//里面执行了扫描Bean,Import,ImportResouce等各种操作
						//用来处理配置类(有两种情况 一种是传统意义上的配置类,一种是普通的bean)的各种逻辑
						currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
						//把name放到processedBeans,后续会根据这个集合来判断处理器是否已经被执行过了
						processedBeans.add(ppName);
					}
				}
				//排序
				sortPostProcessors(currentRegistryProcessors, beanFactory);
				//合并Processors,为什么要合并,因为registryProcessors是装载BeanDefinitionRegistryPostProcessor的
				//一开始的时候,spring只会执行BeanDefinitionRegistryPostProcessor独有的方法
				//而不会执行BeanDefinitionRegistryPostProcessor父类的方法,即BeanFactoryProcessor的方法
				//所以这里需要把处理器放入一个集合中,后续统一执行父类的方法
				registryProcessors.addAll(currentRegistryProcessors);
				//可以理解为执行ConfigurationClassPostProcessor的postProcessBeanDefinitionRegistry方法
				//Spring热插播的体现,像ConfigurationClassPostProcessor就相当于一个组件,Spring很多事情就是交给组件去管理
				//如果不想用这个组件,直接把注册组件的那一步去掉就可以
				invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
				//因为currentRegistryProcessors是一个临时变量,所以需要清除
				currentRegistryProcessors.clear();

				// 再次根据BeanDefinitionRegistryPostProcessor获得BeanName,看这个BeanName是否已经被执行过了,有没有实现Ordered接口
				// 如果没有被执行过,也实现了Ordered接口的话,把对象推送到currentRegistryProcessors,名称推送到processedBeans
				// 如果没有实现Ordered接口的话,这里不把数据加到currentRegistryProcessors,processedBeans中,后续再做处理
				// 这里才可以获得我们定义的实现了BeanDefinitionRegistryPostProcessor的Bean
				postProcessorNames = 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);
				//合并Processors
				registryProcessors.addAll(currentRegistryProcessors);
				//执行我们自定义的BeanDefinitionRegistryPostProcessor
				invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
				currentRegistryProcessors.clear();

				// 上面的代码是执行了实现了Ordered接口的BeanDefinitionRegistryPostProcessor,
				// 下面的代码就是执行没有实现Ordered接口的BeanDefinitionRegistryPostProcessor
				boolean 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();
				}

				// Now, invoke the postProcessBeanFactory callback of all processors handled so far.
				//registryProcessors集合装载BeanDefinitionRegistryPostProcessor
				//上面的代码是执行子类独有的方法,这里需要再把父类的方法也执行一次
				invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
				//regularPostProcessors装载BeanFactoryPostProcessor,执行BeanFactoryPostProcessor的方法
				//但是regularPostProcessors一般情况下,是不会有数据的,只有在外面手动添加BeanFactoryPostProcessor,才会有数据
				invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
			} else {
				// Invoke factory processors registered with the context instance.
				invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
			}

			// Do not initialize FactoryBeans here: We need to leave all regular beans
			// uninitialized to let the bean factory post-processors apply to them!
			//找到BeanFactoryPostProcessor实现类的BeanName数组
			String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

			// Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
			// Ordered, and the rest.
			List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
			List<String> orderedPostProcessorNames = new ArrayList<>();
			List<String> nonOrderedPostProcessorNames = new ArrayList<>();
			for (String ppName : postProcessorNames) {
				//循环数组 如果这个Bean被执行过了,跳过
				if (processedBeans.contains(ppName)) {
					// skip - already processed in first phase above
				} else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
					//如果实现了PriorityOrdered接口,加入到priorityOrderedPostProcessors
					priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
				} else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
					//如果实现了Ordered接口,加入到orderedPostProcessorNames
					orderedPostProcessorNames.add(ppName);
				} else {
					//如果既没有实现PriorityOrdered,也没有实现Ordered。加入到nonOrderedPostProcessorNames
					nonOrderedPostProcessorNames.add(ppName);
				}
			}

			//排序处理priorityOrderedPostProcessors,即实现了PriorityOrdered接口的BeanFactoryPostProcessor
			sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
			//执行priorityOrderedPostProcessors 调用 BeanFactoryPostProcessor#postProcessBeanFactory方法
 			invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

			//执行实现了Ordered接口的BeanFactoryPostProcessor
			List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
			for (String postProcessorName : orderedPostProcessorNames) {
				orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
			}
			sortPostProcessors(orderedPostProcessors, beanFactory);
			invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

			// 执行既没有实现PriorityOrdered接口,也没有实现Ordered接口的BeanFactoryPostProcessor
			List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
			for (String postProcessorName : nonOrderedPostProcessorNames) {
				nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
			}
			invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);

			//清除缓存的合并bean定义,因为后处理器可能已经修改原始元数据,例如替换值中的占位符…
			beanFactory.clearMetadataCache();
		}

整个 invokeBeanFactoryPostProcessors 方法操作了 3 种 bean 对象:
1:入参 beanFactoryPostProcessors:这个是手动注册进去的后置处理器如果没有注册添加则为空,AbstractApplicationContext 类的 beanFactoryPostProcessors 属性值,也就是在之前已经添加到 beanFactoryPostProcessors 中的 BeanFactoryPostProcessor。
2:BeanDefinitionRegistryPostProcessor 接口实现类:实现了 BeanDefinitionRegistryPostProcessor 接口,并且注册到 Spring IoC容器中。
3:常规 BeanFactoryPostProcessor 接口实现类:实现了 BeanFactoryPostProcessor 接口,并且注册到 Spring IoC容器中。

操作3种 bean 对象具体指的是调用它们重写的方法,调用实现方法时会遵循以下的优先级:
第一优先级:入参 beanFactoryPostProcessors 中的 BeanDefinitionRegistryPostProcessor, 调用 postProcessBeanDefinitionRegistry 方法
第二优先级:BeanDefinitionRegistryPostProcessor 接口实现类,并且实现了 PriorityOrdered 接口,调用 postProcessBeanDefinitionRegistry 方法
第三优先级:BeanDefinitionRegistryPostProcessor 接口实现类,并且实现了 Ordered 接口,调用 postProcessBeanDefinitionRegistry 方法
第四优先级:除去第二优先级和第三优先级,剩余的 BeanDefinitionRegistryPostProcessor 接口实现类,调用 postProcessBeanDefinitionRegistry 方法
第五优先级:所有 BeanDefinitionRegistryPostProcessor 接口实现类,调用 postProcessBeanFactory 方法
第六优先级:入参 beanFactoryPostProcessors 中的常规 BeanFactoryPostProcessor,调用 postProcessBeanFactory 方法
第七优先级:常规 BeanFactoryPostProcessor 接口实现类,并且实现了 PriorityOrdered 接口,调用 postProcessBeanFactory 方法
第八优先级:常规 BeanFactoryPostProcessor 接口实现类,并且实现了 Ordered 接口,调用 postProcessBeanFactory 方法
第九优先级:除去第七优先级和第八优先级,剩余的常规 BeanFactoryPostProcessor 接口的实现类,调用 postProcessBeanFactory 

执行步骤:

首先判断beanFactory是不是BeanDefinitionRegistry的实例,当然肯定是的,然后执行如下操作:
1. 定义了一个Set,装载BeanName,后面会根据这个Set,来判断后置处理器是否被执行过了。
2. 定义了两个List,一个是regularPostProcessors,用来装载BeanFactoryPostProcessor,一个是registryProcessors用来装载BeanDefinitionRegistryPostProcessor,其中BeanDefinitionRegistryPostProcessor扩展了BeanFactoryPostProcessor。BeanDefinitionRegistryPostProcessor有两个方法,一个是独有的postProcessBeanDefinitionRegistry方法,一个是父类的postProcessBeanFactory方法。
3. 循环传进来的beanFactoryPostProcessors,上面已经解释过了,一般情况下,这里永远都是空的,只有手动add beanFactoryPostProcessor,这里才会有数据。我们假设beanFactoryPostProcessors有数据,进入循环,判断postProcessor是不是BeanDefinitionRegistryPostProcessor,因为BeanDefinitionRegistryPostProcessor扩展了BeanFactoryPostProcessor,所以这里先要判断是不是BeanDefinitionRegistryPostProcessor,是的话,执行postProcessBeanDefinitionRegistry方法,然后把对象装到registryProcessors里面去,不是的话,就装到regularPostProcessors。
4. 定义了一个临时变量:currentRegistryProcessors,用来装载BeanDefinitionRegistryPostProcessor。
5. getBeanNamesForType,顾名思义,是根据类型查到BeanNames,这里有一点需要注意,就是去哪里找,点开这个方法的话,就知道是循环beanDefinitionNames去找,这个方法以后也会经常看到。这里传了BeanDefinitionRegistryPostProcessor.class,就是找到类型为BeanDefinitionRegistryPostProcessor的后置处理器,并且赋值给postProcessorNames。一般情况下,只会找到一个,就是org.springframework.context.annotation.internalConfigurationAnnotationProcessor,也就是ConfigurationAnnotationProcessor。这个后置处理器在上一节中已经说明过了,十分重要。这里有一个问题,为什么我自己写了个类,实现了BeanDefinitionRegistryPostProcessor接口,也打上了@Component注解,但是这里没有获得,因为直到这一步,Spring还没有完成扫描,扫描是在ConfigurationClassPostProcessor类中完成的,也就是下面第一个invokeBeanDefinitionRegistryPostProcessors方法。
6. 循环postProcessorNames,其实也就是org.springframework.context.annotation.internalConfigurationAnnotationProcessor,判断此后置处理器是否实现了PriorityOrdered接口(ConfigurationAnnotationProcessor也实现了PriorityOrdered接口),
如果实现了,把它添加到currentRegistryProcessors这个临时变量中,再放入processedBeans,代表这个后置处理已经被处理过了。当然现在还没有处理,但是马上就要处理了
7. 进行排序,PriorityOrdered是一个排序接口,如果实现了它,就说明此后置处理器是有顺序的,所以需要排序。当然目前这里只有一个后置处理器,就是ConfigurationClassPostProcessor。
8.把currentRegistryProcessors合并到registryProcessors,为什么需要合并?因为一开始spring只执行BeanDefinitionRegistryPostProcessor独有的方法,而不会执行BeanDefinitionRegistryPostProcessor父类的方法,即BeanFactoryProcessor接口中的方法,所以需要把这些后置处理器放入一个集合中,后续统一执行BeanFactoryProcessor接口中的方法。当然目前这里只有一个后置处理器,就是ConfigurationClassPostProcessor。
9.可以理解为执行currentRegistryProcessors中的ConfigurationClassPostProcessor中的postProcessBeanDefinitionRegistry方法,这就是Spring设计思想的体现了,在这里体现的就是其中的热插拔,插件化开发的思想。Spring中很多东西都是交给插件去处理的,这个后置处理器就相当于一个插件,如果不想用了,直接不添加就是了
10 . 清空currentRegistryProcessors,因为currentRegistryProcessors是一个临时变量,已经完成了目前的使命,所以需要清空,当然后面还会用到。
11.    再次根据BeanDefinitionRegistryPostProcessor获得BeanName,然后进行循环,看这个后置处理器是否被执行过了,如果没有被执行过,也实现了Ordered接口的话,把此后置处理器推送到currentRegistryProcessors和processedBeans中。
这里就可以获得我们定义的,并且打上@Component注解的后置处理器了,因为Spring已经完成了扫描,但是这里需要注意的是,由于ConfigurationClassPostProcessor在上面已经被执行过了,所以虽然可以通过getBeanNamesForType获得,但是并不会加入到currentRegistryProcessors和processedBeans。
12.处理排序。
13.合并Processors,合并的理由和上面是一样的。
14.执行我们自定义的BeanDefinitionRegistryPostProcessor。
15.清空临时变量。
16.在上面的方法中,仅仅是执行了实现了Ordered接口的BeanDefinitionRegistryPostProcessor,这里是执行没有实现Ordered接口的BeanDefinitionRegistryPostProcessor。
17.上面的代码是执行子类独有的方法,这里需要再把父类的方法也执行一次。
18.执行regularPostProcessors中的后置处理器的方法,需要注意的是,在一般情况下,regularPostProcessors是不会有数据的,只有在外面手动添加BeanFactoryPostProcessor,才会有数据。
19.查找实现了BeanFactoryPostProcessor的后置处理器,并且执行后置处理器中的方法。和上面的逻辑差不多,不再详细说明。

还记得这段代码吗

		// 循环传进来的beanFactoryPostProcessors,正常情况下,beanFactoryPostProcessors肯定没有数据 因为beanFactoryPostProcessors是获得手动添加的,而不是spring扫描的
			for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
				if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
					//首先处理BeanDefinitionRegistryPostProcessor 因为BeanDefinitionRegistryPostProcessor也扩展了BeanFactoryPostProcessor
					BeanDefinitionRegistryPostProcessor registryProcessor = (BeanDefinitionRegistryPostProcessor) postProcessor;
					registryProcessor.postProcessBeanDefinitionRegistry(registry);
					registryProcessors.add(registryProcessor);
				} else {
					//不是的话,就装到regularPostProcessors
					regularPostProcessors.add(postProcessor);
				}
			}

注意看registryProcessor.postProcessBeanDefinitionRegistry(registry);会执行 ConfigurationClassPostProcessor类的postProcessBeanDefinitionRegistry方法

	public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
		int registryId = System.identityHashCode(registry);
		if (this.registriesPostProcessed.contains(registryId)) {
			throw new IllegalStateException(
					"postProcessBeanDefinitionRegistry already called on this post-processor against " + registry);
		}
		if (this.factoriesPostProcessed.contains(registryId)) {
			throw new IllegalStateException(
					"postProcessBeanFactory already called on this post-processor against " + registry);
		}
		this.registriesPostProcessed.add(registryId);

		processConfigBeanDefinitions(registry);
	}

主要方法在processConfigBeanDefinitions(registry); 咱们进入方法一探究竟:

public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
		List<BeanDefinitionHolder> configCandidates = new ArrayList<>();
		//获得所有的BeanDefinition的Name,放入candidateNames数组
		String[] candidateNames = registry.getBeanDefinitionNames();

		for (String beanName : candidateNames) {
			BeanDefinition beanDef = registry.getBeanDefinition(beanName);
			// 内部有两个标记位来标记是否已经处理过了
			// 这里会引发一连串知识盲点
			// 当我们注册配置类的时候,可以不加Configuration注解,直接使用Component ComponentScan Import ImportResource注解,称之为Lite配置类
			// 如果加了Configuration注解,就称之为Full配置类
			// 如果我们注册了Lite配置类,我们getBean这个配置类,会发现它就是原本的那个配置类
			// 如果我们注册了Full配置类,我们getBean这个配置类,会发现它已经不是原本那个配置类了,而是已经被cgilb代理的类了
			// 写一个A类,其中有一个构造方法,打印出“你好”
			// 再写一个配置类,里面有两个bean注解的方法
			// 其中一个方法new了A 类,并且返回A的对象,把此方法称之为getA
			// 第二个方法又调用了getA方法
			// 如果配置类是Lite配置类,会发现打印了两次“你好”,也就是说A类被new了两次
			// 如果配置类是Full配置类,会发现只打印了一次“你好”,也就是说A类只被new了一次,因为这个类被cgilb代理了,方法已经被改写
			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)) {
				//判断是否为配置类(有两种情况 一种是传统意义上的配置类,一种是普通的bean),
				//在这个方法内部,会做判断,这个配置类是Full配置类,还是Lite配置类,并且做上标记  MainConfig属于
				//满足条件,加入到configCandidates
				configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
			}
		}
		// 如果没有配置类,直接返回
		// Return immediately if no @Configuration classes were found
		if (configCandidates.isEmpty()) {
			return;
		}

		// Sort by previously determined @Order value, if applicable
		configCandidates.sort((bd1, bd2) -> {
			int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition());
			int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition());
			return Integer.compare(i1, i2);
		});

		// 检测通过封闭应用程序上下文提供的任何自定义bean名称生成策略
		SingletonBeanRegistry sbr = null;
		if (registry instanceof SingletonBeanRegistry) {
			sbr = (SingletonBeanRegistry) registry;
			if (!this.localBeanNameGeneratorSet) {
				//spring中可以修改默认的bean命名方式,这里就是看用户有没有自定义bean命名方式,虽然一般没有人会这么做
				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 class
		//解析每一个 Configuration配置类  目前扫描到新增的 MainConfig
		ConfigurationClassParser parser = new ConfigurationClassParser(
				this.metadataReaderFactory, this.problemReporter, this.environment,
				this.resourceLoader, this.componentScanBeanNameGenerator, registry);

		Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);
		Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size());//空
		do {
			//解析配置类(传统意义上的配置类或者是普通bean,核心来了)
			parser.parse(candidates);
			parser.validate();

			//解析获取得类
			Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());
			configClasses.removeAll(alreadyParsed);

			// Read the model and create bean definitions based on its content
			if (this.reader == null) {
				//
				this.reader = new ConfigurationClassBeanDefinitionReader(
						registry, this.sourceExtractor, this.resourceLoader, this.environment,
						this.importBeanNameGenerator, parser.getImportRegistry());
			}
			//直到这一步才把Import的类,@Bean @ImportRosource 转换成BeanDefinition
			this.reader.loadBeanDefinitions(configClasses);
			//把configClasses加入到alreadyParsed
			alreadyParsed.addAll(configClasses);

			candidates.clear();
			//获得注册器里面BeanDefinition的数量 和 candidateNames进行比较
			//如果大于的话,说明有新的BeanDefinition注册进来了
			if (registry.getBeanDefinitionCount() > candidateNames.length) {
				//从注册器里面获得BeanDefinitionNames
				String[] newCandidateNames = registry.getBeanDefinitionNames();
				//candidateNames转换set
				Set<String> oldCandidateNames = new HashSet<>(Arrays.asList(candidateNames));
				Set<String> alreadyParsedClasses = new HashSet<>();
				//循环alreadyParsed。把类名加入到alreadyParsedClasses

				for (ConfigurationClass configurationClass : alreadyParsed) {
					alreadyParsedClasses.add(configurationClass.getMetadata().getClassName());
				}
				for (String candidateName : newCandidateNames) {
					if (!oldCandidateNames.contains(candidateName)) {
						//新增加的BeanDefinition
						BeanDefinition bd = registry.getBeanDefinition(candidateName);
						//检查给定的bean定义是否是配置类的候选者  以及不在已经解析的类里面
						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 classes
		if (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();
		}
	}
  1. 获得所有的BeanName,放入candidateNames数组。
  2. 循环candidateNames数组,根据beanName获得BeanDefinition,判断此BeanDefinition是否已经被处理过了。
  3. 判断是否是配置类,如果是的话。加入到configCandidates数组,在判断的时候,还会标记配置类属于Full配置类,还是Lite配置类,这里会引发一连串的知识盲点:
    3.1 当我们注册配置类的时候,可以不加@Configuration注解,直接使用@Component @ComponentScan @Import @ImportResource等注解,Spring把这种配置类称之为Lite配置类, 如果加了@Configuration注解,就称之为Full配置类。
    3.2 如果我们注册了Lite配置类,我们getBean这个配置类,会发现它就是原本的那个配置类,如果我们注册了Full配置类,我们getBean这个配置类,会发现它已经不是原本那个配置类了,而是已经被cgilb代理的类了。
    3.3 写一个A类,其中有一个构造方法,打印出“你好”,再写一个配置类,里面有两个被@bean注解的方法,其中一个方法new了A类,并且返回A的对象,把此方法称之为getA,第二个方法又调用了getA方法,如果配置类是Lite配置类,会发现打印了两次“你好”,也就是说A类被new了两次,如果配置类是Full配置类,会发现只打印了一次“你好”,也就是说A类只被new了一次,因为这个类被cgilb代理了,方法已经被改写。
    4.如果没有配置类直接返回。
    5.处理排序。
    6.解析配置类,可能是Full配置类,也有可能是Lite配置类,这个小方法是此方法的核心,稍后具体说明。
    7.在第6步的时候,只是注册了部分Bean,像 @Import @Bean等,是没有被注册的,这里统一对这些进行注册

主要的配置类解析方法ConfigurationClassParser#parse()


	public void parse(Set<BeanDefinitionHolder> configCandidates) {
		//循环传进来的配置类
		for (BeanDefinitionHolder holder : configCandidates) {
			BeanDefinition bd = holder.getBeanDefinition();
			try {
				if (bd instanceof AnnotatedBeanDefinition) {
					//如果获得BeanDefinition是AnnotatedBeanDefinition的实例
					//db 为 AnnotatedGenericBeanDefinition
					parse(((AnnotatedBeanDefinition) bd).getMetadata(), holder.getBeanName());
				} else if (bd instanceof AbstractBeanDefinition && ((AbstractBeanDefinition) bd).hasBeanClass()) {
					parse(((AbstractBeanDefinition) bd).getBeanClass(), holder.getBeanName());
				} else {
					parse(bd.getBeanClassName(), holder.getBeanName());
				}
			}
			catch (BeanDefinitionStoreException ex) {
				throw ex;
			}
			catch (Throwable ex) {
				throw new BeanDefinitionStoreException(
						"Failed to parse configuration class [" + bd.getBeanClassName() + "]", ex);
			}
		}
        //执行DeferredImportSelector
		this.deferredImportSelectorHandler.process();
	}

因为可以有多个配置类,所以需要循环处理。我们的配置类的BeanDefinition是AnnotatedBeanDefinition的实例,所以会进入第一个if

//metadata type 为 StandarAnnotationMetadata
	protected final void parse(AnnotationMetadata metadata, String beanName) throws IOException {
		processConfigurationClass(new ConfigurationClass(metadata, beanName), DEFAULT_EXCLUSION_FILTER);
	}

protected void processConfigurationClass(ConfigurationClass configClass, Predicate<String> filter) throws IOException {
		//判断是否需要跳过 因为它会通过你是否存在Condition条件判断
		if (this.conditionEvaluator.shouldSkip(configClass.getMetadata(), ConfigurationPhase.PARSE_CONFIGURATION)) {
			return;
		}
		//刚开始 configurationClasses是空
		ConfigurationClass existingClass = this.configurationClasses.get(configClass);
		if (existingClass != null) {
			if (configClass.isImported()) {
				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);
			}
		}

		// Recursively process the configuration class and its superclass hierarchy.
		SourceClass sourceClass = asSourceClass(configClass, filter);
		do {
			sourceClass = doProcessConfigurationClass(configClass, sourceClass, filter);
		}
		while (sourceClass != null);

		this.configurationClasses.put(configClass, configClass);
	}


重点在于ConfigurationClassParser#doProcessConfigurationClass方法,会去解析我们的配置类 从解析资源文件 @propertySource @ComponentScan @Import @ImportResource @Bean,需要特别注意,最后一行代码,会把configClass放入一个Map.

	protected final SourceClass doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass, Predicate<String> filter) throws IOException {
		if (configClass.getMetadata().isAnnotated(Component.class.getName())) {
			//递归处理内部类,一般不会写内部类
			// Recursively process any member (nested) classes first
			processMemberClasses(configClass, sourceClass, filter);
		}

		//处理@PropertySource注解,@PropertySource注解用来加载properties文件
		for (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注解具体的内容,ComponentScan注解除了最常用的basePackage之外,还有includeFilters,excludeFilters等
		Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable(sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class);
		//如果没有打上ComponentScan,或者被@Condition条件跳过,就不再进入这个if

		if (!componentScans.isEmpty() && !this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) {
			//循环处理componentScans
			for (AnnotationAttributes componentScan : componentScans) {
				//componentScan就是@ComponentScan上的具体内容,sourceClass.getMetadata().getClassName()就是配置类的名称
				Set<BeanDefinitionHolder> scannedBeanDefinitions = this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());
				for (BeanDefinitionHolder holder : scannedBeanDefinitions) {
					BeanDefinition bdCand = holder.getBeanDefinition().getOriginatingBeanDefinition();
					if (bdCand == null) {
						bdCand = holder.getBeanDefinition();
					}
					if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) {
						//递归调用,因为可能组件类有被@Bean标记的方法,或者组件类本身也有ComponentScan等注解
						parse(bdCand.getBeanClassName(), holder.getBeanName());
					}
				}
			}
		}

		// Process any @Import annotations
		//处理@Import注解
		//@Import注解是spring中很重要的一个注解,Springboot大量应用这个注解
		//@Import三种类,一种是Import普通类,一种是Import ImportSelector,还有一种是Import ImportBeanDefinitionRegistrar
		//getImports(sourceClass)是获得import的内容,返回的是一个set
		processImports(configClass, sourceClass, getImports(sourceClass), filter, true);

		// Process any @ImportResource annotations
		//处理@ImportResource注解
		AnnotationAttributes 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的方法,可以看到获得了带有@Bean的方法后,不是马上转换成BeanDefinition,而是先用一个set接收
		Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass);
		for (MethodMetadata methodMetadata : beanMethods) {
			configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
		}

		// Process default methods on interfaces
		processInterfaces(configClass, sourceClass);

		// Process superclass, if any
		//如果存在父类 处理父类
		if (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 recurse
				return sourceClass.getSuperClass();
			}
		}

		// No superclass -> processing is complete
		return null;
	}
  1. 递归处理内部类,一般不会使用内部类。
  2. 处理@PropertySource注解,@PropertySource注解用来加载properties文件。
  3. 获得ComponentScan注解具体的内容,ComponentScan注解除了最常用的basePackage之外,还有includeFilters,excludeFilters等。
  4. 判断有没有被@ComponentScans标记,或者被@Condition条件带过,如果满足条件的话,进入if,进行如下操作:
    4.1 执行扫描操作,把扫描出来的放入set,这个方法稍后再详细说明。
    4.2 循环set,判断是否是配置类,是的话,递归调用parse方法,因为被扫描出来的类,还是一个配置类,有@ComponentScans注解,或者其中有被@Bean标记的方法 等等,所以需要再次被解析。
    5.处理@Import注解,@Import是Spring中很重要的一个注解,正是由于它的存在,让Spring非常灵活,不管是Spring内部,还是与Spring整合的第三方技术,都大量的运用了@Import注解,@Import有三种情况,一种是Import普通类,一种是Import ImportSelector,还有一种是Import ImportBeanDefinitionRegistrar,getImports(sourceClass)是获得import的内容,返回的是一个set,这个方法稍后再详细说明。
    6.处理@ImportResource注解。
    7.处理@Bean的方法,可以看到获得了带有@Bean的方法后,不是马上转换成BeanDefinition,而是先用一个set接收。
    在这里插入图片描述

看一下解析扫描出来得到的类的处理过程

  		Set<BeanDefinitionHolder> scannedBeanDefinitions = this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());

ComponentScanAnnotationParser#parse


	public Set<BeanDefinitionHolder> parse(AnnotationAttributes componentScan, String declaringClass) {
		//扫描器,还记不记在new AnnotationConfigApplicationContext的时候会调用AnnotationConfigApplicationContext的构造方法
		//构造方法里面有一句 this.scanner = new ClassPathBeanDefinitionScanner(this);
		//当时说这个对象不重要,这里就是证明了。常规用法中,实际上执行扫描的只会是这里的scanner对象
		ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(this.registry,
				componentScan.getBoolean("useDefaultFilters"), this.environment, this.resourceLoader);
		//判断是否重写了默认的命名规则
		Class<? extends BeanNameGenerator> generatorClass = componentScan.getClass("nameGenerator");
		boolean useInheritedGenerator = (BeanNameGenerator.class == generatorClass);
		scanner.setBeanNameGenerator(useInheritedGenerator ? this.beanNameGenerator :
				BeanUtils.instantiateClass(generatorClass));

		ScopedProxyMode scopedProxyMode = componentScan.getEnum("scopedProxy");
		if (scopedProxyMode != ScopedProxyMode.DEFAULT) {
			scanner.setScopedProxyMode(scopedProxyMode);
		}
		else {
			Class<? extends ScopeMetadataResolver> resolverClass = componentScan.getClass("scopeResolver");
			scanner.setScopeMetadataResolver(BeanUtils.instantiateClass(resolverClass));
		}

		scanner.setResourcePattern(componentScan.getString("resourcePattern"));

		//addIncludeFilter addExcludeFilter,最终是往List<TypeFilter>里面填充数据
		//TypeFilter是一个函数式接口,函数式接口在java8的时候大放异彩,只定义了一个虚方法的接口被称为函数式接口
		//当调用scanner.addIncludeFilter  scanner.addExcludeFilter 仅仅把 定义的规则塞进去,并么有真正去执行匹配过程
		//处理includeFilters
		for (AnnotationAttributes filter : componentScan.getAnnotationArray("includeFilters")) {
			for (TypeFilter typeFilter : typeFiltersFor(filter)) {
				scanner.addIncludeFilter(typeFilter);
			}
		}

		//处理excludeFilters
		for (AnnotationAttributes filter : componentScan.getAnnotationArray("excludeFilters")) {
			for (TypeFilter typeFilter : typeFiltersFor(filter)) {
				scanner.addExcludeFilter(typeFilter);
			}
		}

		boolean lazyInit = componentScan.getBoolean("lazyInit");
		//是否懒加载
		if (lazyInit) {
			scanner.getBeanDefinitionDefaults().setLazyInit(true);
		}

		Set<String> basePackages = new LinkedHashSet<>();
		String[] basePackagesArray = componentScan.getStringArray("basePackages");
		for (String pkg : basePackagesArray) {
			String[] tokenized = StringUtils.tokenizeToStringArray(this.environment.resolvePlaceholders(pkg),
					ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);
			Collections.addAll(basePackages, tokenized);
		}
		// 从下面的代码可以看出ComponentScans指定扫描目标,除了最常用的basePackages,还有两种方式
		// 1.指定basePackageClasses,就是指定多个类,只要是与这几个类同级的,或者在这几个类下级的都可以被扫描到,这种方式其实是spring比较推荐的
		// 因为指定basePackages没有IDE的检查,容易出错,但是指定一个类,就有IDE的检查了,不容易出错,经常会用一个空的类来作为basePackageClasses
		// 2.直接不指定,默认会把与配置类同级,或者在配置类下级的作为扫描目标
		for (Class<?> clazz : componentScan.getClassArray("basePackageClasses")) {
			basePackages.add(ClassUtils.getPackageName(clazz));
		}
		if (basePackages.isEmpty()) {
			basePackages.add(ClassUtils.getPackageName(declaringClass));
		}
		//把规则填充到排除规则:List<TypeFilter>,这里就把 注册类自身当作排除规则,真正执行匹配的时候,会把自身给排除
		scanner.addExcludeFilter(new AbstractTypeHierarchyTraversingFilter(false, false) {
			@Override
			protected boolean matchClassName(String className) {
				return declaringClass.equals(className);
			}
		});
		//basePackages是一个LinkedHashSet<String>,这里就是把basePackages转为字符串数组的形式
		return scanner.doScan(StringUtils.toStringArray(basePackages));
	}
  1. 定义了一个扫描器scanner,还记不记在new AnnotationConfigApplicationContext的时候,会调用AnnotationConfigApplicationContext的构造方法,构造方法里面有一句 this.scanner = new ClassPathBeanDefinitionScanner(this);当时说这个对象不重要,这里就是证明了。常规用法中,实际上执行扫描的只会是这里的scanner对象。
  2. 处理includeFilters,就是把规则添加到scanner。
  3. 处理excludeFilters,就是把规则添加到scanner。
  4. 解析basePackages,获得需要扫描哪些包。
  5. 添加一个默认的排除规则:排除自身。
  6. 执行扫描,稍后详细说明。
    这里需要做一个补充说明,添加规则的时候,只是把具体的规则放入规则类的集合中去,规则类是一个函数式接口,只定义了一个虚方法的接口被称为函数式接口,函数式接口在java8的时候大放异彩,这里只是把规则方塞进去,并没有真正执行匹配规则。

具体的扫描包实现在ClassPathBeanDefinitionScanner#doScan

protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
		Assert.notEmpty(basePackages, "At least one base package must be specified");
		Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<>();
		//循环处理basePackages
		for (String basePackage : basePackages) {
			//根据包名找到符合条件的BeanDefinition集合
			Set<BeanDefinition> candidates = findCandidateComponents(basePackage);
			for (BeanDefinition candidate : candidates) {
				ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);
				candidate.setScope(scopeMetadata.getScopeName());
				String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);
				//由findCandidateComponents内部可知,这里的candidate是ScannedGenericBeanDefinition
				//而ScannedGenericBeanDefinition是AbstractBeanDefinition和AnnotatedBeanDefinition的之类
				//所以下面的两个if都会进入
				if (candidate instanceof AbstractBeanDefinition) {
					//内部会设置默认值
					postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);
				}
				if (candidate instanceof AnnotatedBeanDefinition) {
					//如果是AnnotatedBeanDefinition,还会再设置一次值
					AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);
				}
				if (checkCandidate(beanName, candidate)) {
					BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
					definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
					beanDefinitions.add(definitionHolder);
					registerBeanDefinition(definitionHolder, this.registry);
				}
			}
		}
		return beanDefinitions;
	}

因为basePackages可能有多个,所以需要循环处理,最终会进行Bean的注册。下面再来看看findCandidateComponents方法:

	public Set<BeanDefinition> findCandidateComponents(String basePackage) {
		//spring支持component索引技术,需要引入一个组件,因为大部分情况不会引入这个组件
		//所以不会进入到这个if
		if (this.componentsIndex != null && indexSupportsIncludeFilters()) {
			return addCandidateComponentsFromIndex(this.componentsIndex, basePackage);
		}
		else {
			return scanCandidateComponents(basePackage);
		}
	}
public Set<BeanDefinition> findCandidateComponents(String basePackage) {
	//spring支持component索引技术,需要引入一个组件,因为大部分情况不会引入这个组件
	//所以不会进入到这个if
	if (this.componentsIndex != null && indexSupportsIncludeFilters()) {
		return addCandidateComponentsFromIndex(this.componentsIndex, basePackage);
	}
	else {
		return scanCandidateComponents(basePackage);
	}
}

Spring支持component索引技术,需要引入一个组件,大部分项目没有引入这个组件,所以会进入scanCandidateComponents方法:

	private Set<BeanDefinition> scanCandidateComponents(String basePackage) {
		Set<BeanDefinition> candidates = new LinkedHashSet<>();
		try {
			//把 传进来的类似 命名空间形式的字符串转换成类似类文件地址的形式,然后在前面加上classpath*:
			//即:com.xx=>classpath*:com/xx/**/*.class
			String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +
					resolveBasePackage(basePackage) + '/' + this.resourcePattern;
			//根据packageSearchPath,获得符合要求的文件
			Resource[] resources = getResourcePatternResolver().getResources(packageSearchPath);
			boolean traceEnabled = logger.isTraceEnabled();
			boolean debugEnabled = logger.isDebugEnabled();
			//循环资源
			for (Resource resource : resources) {
				//判断资源是否可读,并且不是一个目录
				if (traceEnabled) {
					logger.trace("Scanning " + resource);
				}
				try {
					//metadataReader 元数据读取器,解析resource,也可以理解为描述资源的数据结构
					MetadataReader metadataReader = getMetadataReaderFactory().getMetadataReader(resource);
					//在isCandidateComponent方法内部会真正执行匹配规则
					//注册配置类自身会被排除,不会进入到这个if
					if (isCandidateComponent(metadataReader)) {
						ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader);
						sbd.setSource(resource);
						if (isCandidateComponent(sbd)) {
							if (debugEnabled) {
								logger.debug("Identified candidate component class: " + resource);
							}
							candidates.add(sbd);
						}
						else {
							if (debugEnabled) {
								logger.debug("Ignored because not a concrete top-level class: " + resource);
							}
						}
					}
					else {
						if (traceEnabled) {
							logger.trace("Ignored because not matching any filter: " + resource);
						}
					}
				}
				catch (FileNotFoundException ex) {
					if (traceEnabled) {
						logger.trace("Ignored non-readable " + resource + ": " + ex.getMessage());
					}
				}
				catch (Throwable ex) {
					throw new BeanDefinitionStoreException(
							"Failed to read candidate component class: " + resource, ex);
				}
			}
		}
		catch (IOException ex) {
			throw new BeanDefinitionStoreException("I/O failure during classpath scanning", ex);
		}
		return candidates;
	}
  1. 把传进来的类似命名空间形式的字符串转换成类似类文件地址的形式,然后在前面加上classpath,即:com.xx=>classpath:com/xx/**/*.class。
  2. 根据packageSearchPath,获得符合要求的文件。
  3. 循环符合要求的文件,进一步进行判断。
    最终会把符合要求的文件,转换为BeanDefinition,并且返回

@Import解析:

//这个方法内部相当相当复杂,importCandidates是Import的内容,调用这个方法的时候,已经说过可能有三种情况
	//这里再说下,1.Import普通类,2.Import ImportSelector,3.Import ImportBeanDefinitionRegistrar循环importCandidates,判断属于哪种情况
	//如果是普通类,会进到else,调用processConfigurationClass方法
	//这个方法是不是很熟悉,没错,processImports这个方法就是在processConfigurationClass方法中被调用的
	//processImports又主动调用processConfigurationClass方法,是一个递归调用,因为Import的普通类,也有可能被加了Import注解,
	// @ComponentScan注解 或者其他注解,所以普通类需要再次被解析
	//如果Import ImportSelector就跑到了第一个if中去,首先执行Aware接口方法,所以我们在实现ImportSelector的同时,还可以实现Aware接口
	//然后判断是不是DeferredImportSelector,DeferredImportSelector扩展了ImportSelector
	//如果不是的话,调用selectImports方法,获得全限定类名数组,在转换成类的数组,然后再调用processImports,又特么的是一个递归调用...
	//可能又有三种情况,一种情况是selectImports的类是一个普通类,第二种情况是selectImports的类是一个ImportBeanDefinitionRegistrar类,第三种情况是还是一个ImportSelector类...
	//所以又需要递归调用
	//如果Import ImportBeanDefinitionRegistrar就跑到了第二个if,还是会执行Aware接口方法,这里终于没有递归了,会把数据放到ConfigurationClass中的Map<ImportBeanDefinitionRegistrar, AnnotationMetadata> importBeanDefinitionRegistrars中去
	private void processImports(ConfigurationClass configClass, SourceClass currentSourceClass,
			Collection<SourceClass> importCandidates, Predicate<String> 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) {
					if (candidate.isAssignable(ImportSelector.class)) {
						// Candidate class is an ImportSelector -> delegate to it to determine imports
						Class<?> candidateClass = candidate.loadClass();
						ImportSelector selector = ParserStrategyUtils.instantiateClass(candidateClass, ImportSelector.class,
								this.environment, this.resourceLoader, this.registry);
						Predicate<String> selectorFilter = selector.getExclusionFilter();
						if (selectorFilter != null) {
							exclusionFilter = exclusionFilter.or(selectorFilter);
						}
						if (selector instanceof DeferredImportSelector) {
							this.deferredImportSelectorHandler.handle(configClass, (DeferredImportSelector) selector);
						}
						else {
							String[] importClassNames = selector.selectImports(currentSourceClass.getMetadata());
							Collection<SourceClass> importSourceClasses = asSourceClasses(importClassNames, exclusionFilter);
							processImports(configClass, currentSourceClass, importSourceClasses, exclusionFilter, false);
						}
					}
					else if (candidate.isAssignable(ImportBeanDefinitionRegistrar.class)) {
						// Candidate class is an ImportBeanDefinitionRegistrar ->
						// delegate to it to register additional bean definitions
						Class<?> candidateClass = candidate.loadClass();
						ImportBeanDefinitionRegistrar registrar =
								ParserStrategyUtils.instantiateClass(candidateClass, ImportBeanDefinitionRegistrar.class,
										this.environment, this.resourceLoader, this.registry);
						configClass.addImportBeanDefinitionRegistrar(registrar, currentSourceClass.getMetadata());
					}
					else {
						// Candidate class not an ImportSelector or ImportBeanDefinitionRegistrar ->
						// process it as an @Configuration class
						this.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();
			}
		}
	}

我们来做一个总结,ConfigurationClassPostProcessor中的processConfigBeanDefinitions方法十分重要,主要是完成扫描,最终注册我们定义的Bean。

后面会继续深入再具体完善下,阅读源码确实比较烧脑壳
如果你感觉写的文章对你有帮助,帮忙点个赞呗

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员路同学

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值