Spring-IOC(三)

调用BeanFactoryPostProcessor

接下来进入第一个非常非常复杂的逻辑:获取符合条件的对象,放入beanDefinitionMap中供后续流程的使用

protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
	// getBeanFactoryPostProcessors()其实就是这个类定义的一个list集合,获取手动给spring的BeanFactoryPostProcessor
	// 我们自己通过注解加进来的BeanFactoryPostProcessor不会被这个方法加载进来,通过
	// AnnotationConfigApplicationContext.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()));
	}
}

getBeanFactoryPostProcessors
该方法返回的是beanFactoryPostProcessors集合,这个集合是AbstractApplicationContext的成员属性,那这个集合是什么时候塞值的呢?
看下面这个用例:

public class RunTest2 {

	public static void main(String[] args) {

		AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
		context.register(AppConfig.class);
		context.addBeanFactoryPostProcessor(new MyBeanFactoryPostProcessor());
		context.refresh();
	}
}

这次改变了启动方式,在构建AnnotationConfigApplicationContext对象时不传入AppConfig.class,首先new一个无参构造对象,然后调用register方法将AppConfig.class传入,再次调用addBeanFactoryPostProcessor方法将自定义的BeanFactoryPostProcessor加入到beanFactoryPostProcessors集合中,这样的话再进入getBeanFactoryPostProcessors方法时就有值了

调用PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory, List)方法执行BeanFactoryPostProcessor

判断传入的beanFactory是否是BeanDefinitionRegistry类型,如果是该类型,进入if逻辑,而这个beanFactory其实就是DefaultListableBeanFactory,从该类的UML图可以看出是BeanDefinitionRegistry类型。

BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;

// 定义BeanFactoryPostProcessor集合
List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();

// 定义BeanDefinitionRegistryPostProcessor集合
// 添加自定义的beanFactoryPostProcessor,下面定义的currentRegistryProcessors 是为了添加spring 自定义的
// beanFactoryPostProcessor
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();

// 循环手动注册的beanFactoryPostProcessors,暂时还没找到如何使这个变量有值,所以这里if语句暂时不会执行
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {

	// 如果是BeanDefinitionRegistryPostProcessor的实例话,则调用其postProcessBeanDefinitionRegistry方法,对bean进行注册操作
	if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {

		// 如果是BeanDefinitionRegistryPostProcessor类型,则直接调用其postProcessBeanDefinitionRegistry
		BeanDefinitionRegistryPostProcessor registryProcessor =
				(BeanDefinitionRegistryPostProcessor) postProcessor;
		registryProcessor.postProcessBeanDefinitionRegistry(registry);
		registryProcessors.add(registryProcessor);
	}
	else {
		// 否则将其当做普通的BeanFactoryPostProcessor处理,直接加入regularPostProcessors集合,以备后续处理
		regularPostProcessors.add(postProcessor);
	}
}

// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the bean factory post-processors apply to them!
// Separate between BeanDefinitionRegistryPostProcessors that implement
// PriorityOrdered, Ordered, and the rest.
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();

// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
// 首先调用实现了PriorityOrdered(有限排序接口)的BeanDefinitionRegistryPostProcessors,对于注解的来说,这里的
// postProcessorName其实就是ConfigurationClassPostProcessor,因为这个类实现了BeanDefinitionRegistryPostProcessor接口
// 首先处理的是BeanDefinitionRegistryPostProcessor 接口的实现类,这个接口继承了BeanFactoryPostProcessor
String[] postProcessorNames =
		beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
	// 首先判断是否实现了PriorityOrder接口,ConfigurationClassPostProcessor实现了这个接口
	if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
		currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
		processedBeans.add(ppName);
	}
}

// 排序
sortPostProcessors(currentRegistryProcessors, beanFactory);

// 加入registryProcessors集合
registryProcessors.addAll(currentRegistryProcessors);

// 调用所有实现了PriorityOrdered的BeanDefinitionRegistryPostProcessors的postProcessBeanDefinitionRegistry方法,
// 注册所有使用Spring组件注解的bean
// 这里取到的BeanDefinitionRegistryPostProcessor是ConfigurationClassPostProcessor
// 所以会在调用BeanFactoryPostProcessor的时候会进入ConfigurationClassPostProcessor对应的处理器中
// 走完这步说明已经将程序员自己写的bean 放入到了DefaultListableBeanFactory 中了
// 对于注解的话 currentRegistryProcessors 这个是 ConfigurationClassPostProcessor
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);

// 清空currentRegistryProcessors,以备下次使用
currentRegistryProcessors.clear();

// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
// 其次,调用实现了Ordered(普通排序接口)的BeanDefinitionRegistryPostProcessors
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
	// 这里会做一个判断,如果processedBeans中包含了processor,则这里就不会执行,因为ConfigurationClassPostProcessor既实现了PriorityOrder
	// 接口又实现了Orderd接口,在上面代码匹配到时就已经将该processor添加到processedBeans中了,所以这里就不会再执行
	if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
		currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
		processedBeans.add(ppName);
	}
}

// 排序
sortPostProcessors(currentRegistryProcessors, beanFactory);

// 加入registryProcessors集合
registryProcessors.addAll(currentRegistryProcessors);

// 调用所有实现了PriorityOrdered的的BeanDefinitionRegistryPostProcessors的postProcessBeanDefinitionRegistry方法,注册bean
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);

// 清空currentRegistryProcessors,以备下次使用
currentRegistryProcessors.clear();

// Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
// 最后,调用其他的BeanDefinitionRegistryPostProcessors,这里是既没有实现PriorityOrdered接口又没有实现Ordered接口的processor
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集合
	registryProcessors.addAll(currentRegistryProcessors);

	// 调用其他的BeanDefinitionRegistryPostProcessors的postProcessBeanDefinitionRegistry方法,注册bean
	invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);

	// 清空currentRegistryProcessors,以备下次使用
	currentRegistryProcessors.clear();
}

// Now, invoke the postProcessBeanFactory callback of all processors handled so far.
// 调用所有BeanDefinitionRegistryPostProcessor(包括手动注册和通过配置文件注册)
// 和BeanFactoryPostProcessor(只有手动注册)的回调函数-->postProcessBeanFactory
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);

上面这段代码就是if逻辑中全部代码,在说这块代码之前需要说两个接口:BeanDefinitionRegistryPostProcessor和BeanFactoryPostProcessor,其中BeanDefinitionRegistryPostProcessor接口继承了BeanFactoryPostProcessor接口。我们知道在第一篇文章中说到了spring加载了六个processor,其中有个processor是ConfigurationClassPostProcessor,而这个类实现了BeanDefinitionRegistryPostProcessor接口,那么也就间接实现了BeanFactoryPostProcessor接口。

ConfigurationClassPostProcessor-UML图
image

  • 首先判断传入的beanFactoryPostProcessors是否为空,这个是程序员通过调用addBeanFactoryPostProcessor方法添加的processor,一般为空
  • 从beanFactory中获取BeanDefinitionRegistryPostProcessor类型的bean,这个bean其实就是ConfigurationClassPostProcessor
  • 判断该bean是否实现了PriorityOrdered接口,如果实现该接口加入到currentRegistryProcessors集合中并且添加到processedBeans集合中,显然ConfigurationClassPostProcessor实现了PriorityOrdered接口
  • 对currentRegistryProcessors集合排序
  • 将currentRegistryProcessors集合中的数据加入到registryProcessors集合中
  • 调用invokeBeanDefinitionRegistryPostProcessors方法执行BeanDefinitionRegistryPostProcessor接口中的postProcessBeanDefinitionRegistry方法,这步是关键,因为会扫描项目中所有符合spring条件的bean
  • 清空currentRegistryProcessors,为下次使用
  • 判断该bean是否实现了Ordered接口,如果实现了该接口加入到currentRegistryProcessors集合中,显然ConfigurationClassPostProcessor实现了Ordered接口,但不会添加到currentRegistryProcessors集合中,以为在判断是否实现PriorityOrdered接口时除了添加到currentRegistryProcessors集合中以外还添加到processedBeans集合中。这里判断是否需要添加到currentRegistryProcessors集合中的条件除了要实现Ordered接口以外,processedBeans集合中也不能有数据,所以这里不会将ConfigurationClassPostProcessor类再次添加到currentRegistryProcessors集合中,防止了重复执行的逻辑
  • 重复上面的步骤,对currentRegistryProcessors进行排序,添加到registryProcessors集合中,调用invokeBeanDefinitionRegistryPostProcessors方法执行eanDefinitionRegistryPostProcessor接口中的postProcessBeanDefinitionRegistry方法,清空currentRegistryProcessors,为下次使用
  • 最后找出既没实现PriorityOrdered接口,也没实现Ordered接口并且不再processBeans集合中的processor,添加到currentRegistryProcessors集合中,重复上面的步骤

if条件中的逻辑说完了,整理出来其实很简单,就是如下几个步骤:

  1. 收集手工添加的BeanFactoryPostProcessor类型的processor,添加到registryProcessors集合中
  2. 收集spring中BeanDefinitionRegistryPostProcessor类型并且实现了PriorityOrdered接口的processor添加到currentRegistryProcessors集合中
  3. 对currentRegistryProcessors集合排序,执行BeanDefinitionRegistryPostProcessor接口的postProcessBeanDefinitionRegistry方法
  4. 清空currentRegistryProcessors集合
  5. 收集pring中BeanDefinitionRegistryPostProcessor类型并且实现了Ordered接口的processor添加到currentRegistryProcessors集合中
  6. 对currentRegistryProcessors集合排序,执行BeanDefinitionRegistryPostProcessor接口的postProcessBeanDefinitionRegistry方法
  7. 清空currentRegistryProcessors集合
  8. 收集spring中BeanDefinitionRegistryPostProcessor类型并且既没有实现PriorityOrdered接口也没有实现Ordered接口的processor添加到currentRegistryProcessors集合中
  9. 对currentRegistryProcessors集合排序,执行BeanDefinitionRegistryPostProcessor接口的postProcessBeanDefinitionRegistry方法
  10. 清空currentRegistryProcessors集合

这样整理出来就清晰明了了,其实从第五步开始都是和第二步、第三步重复的,只不过逻辑稍微改变下而已。从上面的步骤可以看出最重要的就是第三步了,执行BeanDefinitionRegistryPostProcessor接口的postProcessBeanDefinitionRegistry方法

private static void invokeBeanDefinitionRegistryPostProcessors(
		Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry) {

	for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {
		postProcessor.postProcessBeanDefinitionRegistry(registry);
	}
}

这里主要是遍历postProcessors并执行postProcessBeanDefinitionRegistry方法,这里的postProcessor只有一个:ConfigurationClassPostProcessor

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方法的执行

public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
	List<BeanDefinitionHolder> configCandidates = new ArrayList<>();
        // 从registry获取beanDefinitionNames,其实就是从DefaultListableBeanFactory中获取beanDefinitionNames
	String[] candidateNames = registry.getBeanDefinitionNames();

	// 这里得到的candidateNames数组中的数据除了刚开始spring自动添加了几个processor会被放入beanDefinitionMap中,还有一个是程序员自己定义的类,这个类是在
	// AnnotationConfigApplicationContext构造方法中传入的,这个也会被加入到beanDefinitionMap中。
	for (String beanName : candidateNames) {
		// 这里其实就是从DefaultListableBeanFactory中的beanDefinitionMap中取出beanName对应的BeanDefinition
		// isFullConfigurationClass 和 isLiteConfigurationClass 判断该 bean 是 Full 属性还是 lite 属性
		// 这个Full和lite类型的区分是为了后续cglib代理做准备。含有@Configuration注解的是Full类型,ComponentScan、Component、Import
		// 、ImportResource等注解的是lite类型
		BeanDefinition beanDef = registry.getBeanDefinition(beanName);
		if (ConfigurationClassUtils.isFullConfigurationClass(beanDef) ||
				ConfigurationClassUtils.isLiteConfigurationClass(beanDef)) {
			if (logger.isDebugEnabled()) {
				logger.debug("Bean definition has already been processed as a configuration class: " + beanDef);
			}
		}
		// 1.如果当前的bean是Javabean配置类(含有@Configuration注解的类或者ComponentScan、Component、Import、ImportResource注解,
		// 如果没有就查找Bean注解)如果找到设置beanDef的attribute对应的class为ConfigurationClassPostProcessor,
		// 然后再加入到集合configCandidates中
		else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
			configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
		}
	}

	// 对于注解的例子 Main.java 来说,程序走到这里 configCandidates 中只有一个:httpConfig
	// Return immediately if no @Configuration classes were found
	// 没有@Configuration的类就退出
	if (configCandidates.isEmpty()) {
		return;
	}
	// 走到这里说明在 candidateNames 中
	// 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);
	});

	// Detect any custom bean name generation strategy supplied through the enclosing application context
	SingletonBeanRegistry sbr = null;
	if (registry instanceof SingletonBeanRegistry) {
		sbr = (SingletonBeanRegistry) registry;
		if (!this.localBeanNameGeneratorSet) {
			// beanName的生成器,因为后面会扫描出所有加入到spring容器中class类,然后把这些class
			// 解析成BeanDefinition类,此时需要利用BeanNameGenerator为这些BeanDefinition生成beanName

			BeanNameGenerator generator = (BeanNameGenerator) sbr.getSingleton(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
	// 初始化 ConfigurationClassParser 类
	ConfigurationClassParser parser = new ConfigurationClassParser(
			this.metadataReaderFactory, this.problemReporter, this.environment,
			this.resourceLoader, this.componentScanBeanNameGenerator, registry);

	// 使用 set 是为了去重,防止解析到同一个 bean
	Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);
	Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size());
	do {
		// 2.解析java配置类,这里只是将这些注解的java组装成BeanDefinition对象
		parser.parse(candidates);
		// 这个主要校验java配置类不能是final类型的,因为cglib代理的是类,如果这个类是final的话
		// cglib就无法对这个类创建一个子类来进行增强
		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());
		}

		// 3.加载bean定义信息,主要是将@Bean,@Configuration,@Import,@ImportResource,@ImportRegistry注册为bean
		this.reader.loadBeanDefinitions(configClasses);
		alreadyParsed.addAll(configClasses);

		candidates.clear();

		// 再次获取bean定义的数量,如果这个数量大于之前的数量说明这个过程中有新的bean加入,还要进行解析
		if (registry.getBeanDefinitionCount() > candidateNames.length) {
			String[] newCandidateNames = registry.getBeanDefinitionNames();
			Set<String> oldCandidateNames = new HashSet<>(Arrays.asList(candidateNames));
			Set<String> 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 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();
	}
}
  • 首先获取beanDefinitionNames,这里的beanDefinitionNames有以下几个:

org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
appConfig

除了最后一个是我们自己的类通过spring添加进去的,其余的几个都是spring工程自己的,这些都是在构造AnnotatedBeanDefinitionReader对象时生成的

  • 进入for循环,循环遍历这些beanDefinitionNames
    • 根据beanName获取对应的BeanDefinition对象
    • 判断这些BeanDefinition对象是是Full还是Lite(判断这个主要是为了后续的增强,这里可以先记住这点
    • 将符合条件的BeanDefinition加入到configCandidates中
      判断一个BeanDefinition是Full还是Lite

private static final String CONFIGURATION_CLASS_FULL = "full";

private static final String CONFIGURATION_CLASS_LITE = "lite";
private static final String CONFIGURATION_CLASS_ATTRIBUTE =
	Conventions.getQualifiedAttributeName(ConfigurationClassPostProcessor.class, "configurationClass");

public static boolean isFullConfigurationClass(BeanDefinition beanDef) {
	return CONFIGURATION_CLASS_FULL.equals(beanDef.getAttribute(CONFIGURATION_CLASS_ATTRIBUTE));
}

public static boolean isLiteConfigurationClass(BeanDefinition beanDef) {
	return CONFIGURATION_CLASS_LITE.equals(beanDef.getAttribute(CONFIGURATION_CLASS_ATTRIBUTE));
}

第一次进来肯定既不是full也不是lite,所以这里的if条件不会执行

判断BeanDefinition是否是符合条件
这里判断BeanDefinition是否符合条件,如果符合,就添加到configCandidates集合中

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();
		metadata = new StandardAnnotationMetadata(beanClass, true);
	}
	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关联
	// 该方法还会查找该注解上是否存在@Configuration注解,会一直往上找,因为有些注解是复合注解
	if (isFullConfigurationCandidate(metadata)) {
		beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_FULL);
	}
	// 查找当前注解是否含有ComponentScan、Component、Import、ImportResource注解,如果没有就查找Bean注解,原理同上
	else if (isLiteConfigurationCandidate(metadata)) {
		beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_LITE);
	}
	else {
		return false;
	}

	// It's a full or lite configuration candidate... Let's determine the order value, if any.
	Integer order = getOrder(metadata);
	if (order != null) {
		beanDef.setAttribute(ORDER_ATTRIBUTE, order);
	}

	return true;
}

该方法主要的流程是首先获取对应的注解元数据,从注解元数据中找出是full还是lite,如果两者都不是,那么返回false;如果是full或者lite,那么再从元数据中获取order注解,如果order注解存在,那么对应的BeanDefinition设置order属性,最后返回true

如何判断是full还是lite

private static final Set<String> candidateIndicators = new HashSet<>(8);

static {
	candidateIndicators.add(Component.class.getName());
	candidateIndicators.add(ComponentScan.class.getName());
	candidateIndicators.add(Import.class.getName());
	candidateIndicators.add(ImportResource.class.getName());
}



public static boolean isFullConfigurationCandidate(AnnotationMetadata metadata) {
	return metadata.isAnnotated(Configuration.class.getName());
}


public static boolean isLiteConfigurationCandidate(AnnotationMetadata metadata) {
	// Do not consider an interface or an annotation...
	if (metadata.isInterface()) {
		return false;
	}

	// Any of the typical annotations found?
	for (String indicator : candidateIndicators) {
		if (metadata.isAnnotated(indicator)) {
			return true;
		}
	}

	// Finally, let's look for @Bean methods...
	try {
		return metadata.hasAnnotatedMethods(Bean.class.getName());
	}
	catch (Throwable ex) {
		if (logger.isDebugEnabled()) {
			logger.debug("Failed to introspect @Bean methods on class [" + metadata.getClassName() + "]: " + ex);
		}
		return false;
	}
}

代码很简单,从代码中可以看出如果注解元数据中含有@Configuration注解的话,那么就是full;如果注解元数据中含有@Component、@ComponentScan、@Import、@ImportResource注解的话属于lite,如果没有这几种注解的话,那么就判断方法上是否含有@Bean注解,如果存在那么就是lite,否则就返回false。
如果该BeanDefinition属于full或者lite的话,那么就在对应BeanDefinition中设置对应的属性是full还是lite

  • for循环执行完毕,接着判断configCandidates集合中是否有数据,如果没有数据直接return,方法结束
  • 对configCandidates集合中的BeanDefinition进行排序
  • 生成beanName
  • 判断environment是否为null,如果为null,则创建StandardEnvironment对象赋值给environment
  • 初始化ConfigurationClassParser对象,这个对象主要是为了后面的解析
  • 将configCandidates集合添加进一个set集合:candidates,主要是为了去重
  • 创建一个set集合:alreadyParsed,该集合的长度是configCandidates长度,主要是用来保存已经解析过的BeanDefinition
  • 调用ConfigurationClassParser#parse方法对candidates进行解析
  • 调用ConfigurationClassParser#validate方法进行校验
  • 创建一个set集合:configClasses,用来存放ConfigurationClassParser#parse解析过程中的配置类
  • 加载BeanDefinition,加载是configClasses集合中BeanDefinition
  • 再次获取bean定义的数量,如果这个数量大于之前的数量说明这个过程中有新的bean加入,还要进行解析
    到这processConfigBeanDefinitions这个方法的逻辑就说完了,在剩下的这些步骤中需要注意的有三点,两个是和ConfigurationClassParser有关的:一个是parse方法,一个是validate方法,还有最后一个loadBeanDefinitions方法
posted @ 2021-07-28 15:36  扭不动的奥利奥  阅读(61)  评论(0)    收藏  举报