Spring中@Configuration源码深度解析(一)

      我们知道@Configuration 和 @Component都可以向String容器中注入bean对象,但是他们之前还是有不同点的。Spring中@Configuration源码深度解析(二)的传送门:Spring中@Configuration源码深度解析(二)

     下面直接看@Configuration的源码,关于@Configuration的使用,后面有机会写篇文章:

package com.luban.configuration;

@Configuration
@ComponentScan("com.luban.configuration")
public class Config {

	@Bean
	public School school() {
		return new School();
	}
}

public class Test01 {
	public static void main(String[] args) {
		AnnotationConfigApplicationContext context = 
                      new AnnotationConfigApplicationContext(Config.class); //以这句代码为入口进行分析
	}
}

  代码块1. AnnotationConfigApplicationContext#AnnotationConfigApplicationContext方法

/**
 * 这个构造方法需要传入一个被javaconfig注解了的配置类
 * 然后会把这个被注解了javaconfig的类通过注解读取器读取后继而解析
 */
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
	//1.annotatedClasses  appconfig.class
	//在自己构造方法中初始一个读取器和扫描器
	//这句代码内部会创建一个AnnotatedBeanDefinitionReader对象,在创建这个对象时
	//会向容器中注入多个后置处理器,其中有一个是用来完成
	//指定包扫描,并把普通的标了注解的Java类,解析成beanDefinition对象
	//并放到一个Map中,这个后置处理为ConfigurationClassPostProcessor
	this();
	//2.将配置类注册到容器中
	register(annotatedClasses);
	//3.完成容器刷新,就是在这一步容器完成bean的创建
	refresh();
}

      其中第3步,会调用refresh会完成容器刷新,看代码块2,就是在这一步容器完成bean的创建,前面两步注释已经写的很清楚了,想要深入了解的话,可以点进去看一下,这篇文档只是让你了解加了@Configuration后,Spring会怎么进行解析,就不在介绍了。

  代码块2. AbstractApplicationContext#refresh方法

//这个方法可以说是Spring中最重要的一个方法,也用到了模板方法模式
@Override
public void refresh() throws BeansException, IllegalStateException {
	synchronized (this.startupShutdownMonitor) {
		// Prepare this context for refreshing.
		////1.准备工作包括设置启动时间,是否激活标识位,
		// 初始化属性源(property source)配置
		prepareRefresh();

		// Tell the subclass to refresh the internal bean factory.
		//2.返回一个factory 为什么需要返回一个工厂
		//因为要对工厂进行初始化
		ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

		// Prepare the bean factory for use in this context.
		//3.准备工厂
		prepareBeanFactory(beanFactory);

		try {
			// Allows post-processing of the bean factory in context subclasses.

			//4. 这个方法在当前版本的spring是没用任何代码的
			//可能spring期待在后面的版本中去扩展吧
			postProcessBeanFactory(beanFactory);

			// 5. Invoke factory processors registered as beans in the context.
			//在spring的环境中去执行已经被注册的 factory processors
			//设置执行自定义的ProcessBeanFactory 和spring内部自己定义的
			//在该步会进行注解的解析,并完成普通对象到beanDefinition的转变
			//其中@Configuration也是在这步完成的
			invokeBeanFactoryPostProcessors(beanFactory);

			// Register bean processors that intercept bean creation.
			//6. 注册beanPostProcessor
			registerBeanPostProcessors(beanFactory);

			//7. Initialize message source for this context.
			initMessageSource();

			// Initialize event multicaster for this context.
			//8. 初始化应用事件广播器
			initApplicationEventMulticaster();

			//9. Initialize other special beans in specific context subclasses.
			onRefresh();

			//10. Check for listener beans and register them.
			registerListeners();

			//11. Instantiate all remaining (non-lazy-init) singletons.
			//该步会根据beanDefinition完成剩下的非懒加载的bean
			finishBeanFactoryInitialization(beanFactory);

			//12. Last step: publish corresponding event.
			finishRefresh();
		}

		catch (BeansException ex) {
			if (logger.isWarnEnabled()) {
				logger.warn("Exception encountered during context initialization - " +
						"cancelling refresh attempt: " + ex);
			}

			// Destroy already created singletons to avoid dangling resources.
			destroyBeans();

			// Reset 'active' flag.
			cancelRefresh(ex);

			// Propagate exception to caller.
			throw ex;
		}

		finally {
			// Reset common introspection caches in Spring's core, since we
			// might not ever need metadata for singleton beans anymore...
			resetCommonCaches();
		}
	}
}

      在第5步中会完成普通对象到beanDefinition的转换,然后在第11步会根据beanDefinition完成剩下的非懒加载的bean,我们这里我们只关注第5步就行,第5步是执行BeanFactory的后置处理器,这是Spring提供的扩展点之一,在这个扩展点中允许我们在bean实例话之前做一些操作,看代码块3

  代码块3. AbstractApplicationContext#invokeBeanFactoryPostProcessors方法

protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
	//这个地方需要注意getBeanFactoryPostProcessors()是获取手动给spring的BeanFactoryPostProcessor
	//自定义并不仅仅是程序员自己写的
	//自己写的可以加companent也可以不加
	//如果加了getBeanFactoryPostProcessors()这个地方得不得,是spring自己扫描的
	//为什么得不到getBeanFactoryPostProcessors()这个方法是直接获取一个list,
	//这个list是在AnnotationConfigApplicationContext被定义
	//所谓的自定义的就是你手动调用AnnotationConfigApplicationContext.addBeanFactoryPostProcesor();
	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()));
	}
}

      会调用PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors来完成BeanFactoryPostProcessors后置处理的调用工作,看代码块4

  代码块4. PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors方法

  这里先说一下,之前我们提到ConfigurationClassPostProcessor类,先来看一下它的继承关系:

            

        invokeBeanFactoryPostProcessors的代码比较长,我先说一下做了什么事,这样便于大家在看源码,这个方法会调用所有实现了BeanDefinitionRegistryPostProcessor和BeanFactoryPostProcessor的方法(BeanDefinitionRegistryPostProcessor和BeanFactoryPostProcessor是继承关系),首先他会拿到容器内部所有的BeanFactoryPostProcessor,也就是自定义,判断是否有BeanDefinitionRegistryPostProcessor类型的,如果是,执行BeanDefinitionRegistryPostProcessor接口的方法,然后根据名称先查找所有的BeanDefinitionRegistryPostProcessor接口,根据实现了PriorityOrdered、Ordered和普通的依次调用其BeanDefinitionRegistryPostProcessor接口的方法,然后在执行是BeanDefinitionRegistryPostProcessor类型的BeanFactoryPostProcessor接口的postProcessBeanFactory方法,因为一个类如果是BeanDefinitionRegistryPostProcessor类型的,那么它必然属于BeanFactoryPostProcessor类型的。

       然后根据类型再查找所有的BeanFactoryPostProcessor类型,根据根据实现了PriorityOrdered、Ordered和普通的依次调用其postProcessBeanFactory方法。

       其中PriorityOrdered、Ordered是Spring用来排序用的,可以规定谁先执行,谁后执行。

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

	// Invoke BeanDefinitionRegistryPostProcessors first, if any.
	Set<String> processedBeans = new HashSet<>();

	if (beanFactory instanceof BeanDefinitionRegistry) {
		BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;

		List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
		List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();

		//自定义的beanFactoryPostProcessors
		for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
			if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
				BeanDefinitionRegistryPostProcessor registryProcessor =
						(BeanDefinitionRegistryPostProcessor) postProcessor;
				registryProcessor.postProcessBeanDefinitionRegistry(registry);
				registryProcessors.add(registryProcessor);
			}
			else {//BeanDefinitionRegistryPostProcessor  BeanfactoryPostProcessor
				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.
		//这个currentRegistryProcessors 放的是spring内部自己实现了BeanDefinitionRegistryPostProcessor接口的对象
		//我的理解:currentRegistryProcessors存在的正在遍历的实现了BeanDefinitionRegistryPostProcessor接口的对象,然后将
		//之保存起来,进行调用,调用之后,清空

		List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();

		// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
		//BeanDefinitionRegistryPostProcessor 等于 BeanFactoryPostProcessor
		//getBeanNamesForType  根据bean的类型获取bean的名字ConfigurationClassPostProcessor
		String[] postProcessorNames =
				beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
		//这个地方可以得到一个BeanFactoryPostProcessor,因为是spring默认在最开始自己注册的
		//为什么要在最开始注册这个呢?
		//因为spring的工厂需要许解析去扫描等等功能
		//而这些功能都是需要在spring工厂初始化完成之前执行
		//要么在工厂最开始的时候、要么在工厂初始化之中,反正不能再之后
		//因为如果在之后就没有意义,因为那个时候已经需要使用工厂了
		//所以这里spring'在一开始就注册了一个BeanFactoryPostProcessor,用来插手springfactory的实例化过程
		//在这个地方断点可以知道这个类叫做ConfigurationClassPostProcessor
		//ConfigurationClassPostProcessor那么这个类能干嘛呢?可以参考源码
		//下面我们对这个牛逼哄哄的类(他能插手spring工厂的实例化过程还不牛逼吗?)重点解释
		for (String ppName : postProcessorNames) {
			if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
				currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
				processedBeans.add(ppName);
			}
		}
		//排序不重要,况且currentRegistryProcessors这里也只有一个数据
		sortPostProcessors(currentRegistryProcessors, beanFactory);
		//合并list,不重要(为什么要合并,因为还有自己的)
		//我的理解:合并之后集中进行调用BeanFactoryPostProcessor接口的postProcessBeanFactory
		registryProcessors.addAll(currentRegistryProcessors);
		
		
		//1. 最重要。注意这里是方法调用
		//执行所有BeanDefinitionRegistryPostProcessor
		//因为ConfigurationClassPostProcessor实现了PriorityOrdered接口,所以会在这个调用ConfigurationClassPostProcessor
		//类的postProcessBeanDefinitionRegistry方法
		invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
		//执行完成了所有BeanDefinitionRegistryPostProcessor
		//这个list只是一个临时变量,故而要清除
		currentRegistryProcessors.clear();

		// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
		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);
		registryProcessors.addAll(currentRegistryProcessors);
		invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
		currentRegistryProcessors.clear();

		// Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
		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();
		}

		//2. Now, invoke the postProcessBeanFactory callback of all processors handled so far.
		//执行BeanFactoryPostProcessor的回调,前面不是吗?
		//前面执行的BeanFactoryPostProcessor的子类BeanDefinitionRegistryPostProcessor的回调
		//这是执行的是BeanFactoryPostProcessor    postProcessBeanFactory
		//ConfuguratuonClassPpostProcssor
		//这里执行的是BeanFactoryPostProcessor接口的方法,因为在找到并执行BeanDefinitionRegistryPostProcessor接口的方法后,
		//又因为BeanDefinitionRegistryPostProcessor继承与BeanFactoryPostProcessor,所以此时BeanFactoryPostProcessor的接
		//口还没执行的
		//这一步会调用实现了BeanDefinitionRegistryPostProcessor接口的,父类方法,
		//标注了@Configuration注解的类,会在这个得到增强
		invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
		//自定义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!
	//ConfigurationClassPostProcessor
	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) {
		//processedBeans里面保存是在执行BeanDefinitionRegistryPostProcessor的时候已经执行过了BeanFactoryPostProcessor接口的方法
		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<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>();
	for (String postProcessorName : orderedPostProcessorNames) {
		orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
	}
	sortPostProcessors(orderedPostProcessors, beanFactory);
	invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

	// Finally, invoke all other BeanFactoryPostProcessors.
	List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
	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();
}

       最重要的和@Configuration相关的就是上述代码块中标注了第1步和第2步的地方。

       invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);会将普通注解类转换成beanDefinition对象,看代码块5

       invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);会根据一个类是否标有@Configuration来进行增强,由于篇幅有限,关于这个方法放到了Spring中@Configuration源码深度解析(二)里面进行讲解。

  代码块5. PostProcessorRegistrationDelegate#invokeBeanDefinitionRegistryPostProcessors方法

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

         //循环调用所有的BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法
	for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {
	       //走到这里就会调用ConfigurationClassPostProcessor的postProcessBeanDefinitionRegistry方法了
		postProcessor.postProcessBeanDefinitionRegistry(registry);
	}
}

  代码块6.ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry方法

      首先说明一下在这个processConfigBeanDefinitions方法中会做很多事情,会解析类上面标注了@ComponentScan、@Import、@bean、@Component等注解信息,对于@ComponentScan会解析出需要扫描的包,然后利用ASM技术得到这个类,然后再次解析类上面的注解,对于@Import来说,由于支持带入普通类、ImportSelector的实现类和ImportBeanDefinitionRegistrar的实现了,所以在解析@Import的时候,会进行判断三种情况,然后执行ImportBeanDefinitionRegistrar和ImportSelector接口中的方法,对于导入的类,也会进行判断类中标注的注解(使用递归),

这里简单这样说一下,不做过多介绍,只介绍Spring对于@Configuration是怎么处理的。

@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
       //得到一个hash值,判断是否已经解析过这个对象了
	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);
        //真正完成从普通注解类到beanDefinition的转换
	processConfigBeanDefinitions(registry);
}

public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
	//1. 定义一个list存放app 提供的bd(项目当中提供了@Compent)
	List<BeanDefinitionHolder> configCandidates = new ArrayList<>();
	//2. 获取容器中注册的所有bd名字
	String[] candidateNames = registry.getBeanDefinitionNames();

	/**
	 * Full
	 * Lite
	 */
	for (String beanName : candidateNames) {
		BeanDefinition beanDef = registry.getBeanDefinition(beanName);
		if (ConfigurationClassUtils.isFullConfigurationClass(beanDef) ||
				ConfigurationClassUtils.isLiteConfigurationClass(beanDef)) {
			//3. 如果BeanDefinition中的configurationClass属性为full或者lite,则意味着已经处理过了,直接跳过
		}
		//4. 判断是否是Configuration类,如果加了Configuration下面的这几个注解就不再判断了
		// 还有  add(Component.class.getName());
		//		candidateIndicators.add(ComponentScan.class.getName());
		//		candidateIndicators.add(Import.class.getName());
		//		candidateIndicators.add(ImportResource.class.getName());
		else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
			//BeanDefinitionHolder 也可以看成一个数据结构
			configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
		}
	}

	// Return immediately if no @Configuration classes were found
	if (configCandidates.isEmpty()) {
		return;
	}

	// 5. 排序,根据order,不重要
	// 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;
	// 6. 如果BeanDefinitionRegistry是SingletonBeanRegistry子类的话,
	// 由于我们当前传入的是DefaultListableBeanFactory,是SingletonBeanRegistry 的子类
	// 因此会将registry强转为SingletonBeanRegistry
	//主要是生成bean的名字生成器
	if (registry instanceof SingletonBeanRegistry) {
		sbr = (SingletonBeanRegistry) registry;
		if (!this.localBeanNameGeneratorSet) {//是否有自定义的
			BeanNameGenerator generator = (BeanNameGenerator) sbr.getSingleton(CONFIGURATION_BEAN_NAME_GENERATOR);
			//SingletonBeanRegistry中有id为 org.springframework.context.annotation.internalConfigurationBeanNameGenerator
			//如果有则利用他的,否则则是spring默认的
			if (generator != null) {
				this.componentScanBeanNameGenerator = generator;
				this.importBeanNameGenerator = generator;
			}
		}
	}

	if (this.environment == null) {
		this.environment = new StandardEnvironment();
	}

	// Parse each @Configuration class
	//7. 实例化ConfigurationClassParser 为了解析各个配置类
	ConfigurationClassParser parser = new ConfigurationClassParser(
			this.metadataReaderFactory, this.problemReporter, this.environment,
			this.resourceLoader, this.componentScanBeanNameGenerator, registry);

	//实例化2个set,candidates用于将之前加入的configCandidates进行去重,Spring内部没有重复的,就怕你给他一个重复的
	//因为可能有多个配置类重复了
	//alreadyParsed用于判断是否处理过
	Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);
	Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size());
	do {
		parser.parse(candidates);
		parser.validate();
		//map.keyset
		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());
		}

		/**
		 * 这里值得注意的是扫描出来的bean当中可能包含了特殊类
		 * 比如ImportBeanDefinitionRegistrar那么也在这个方法里面处理
		 * 但是并不是包含在configClasses当中
		 * configClasses当中主要包含的是importSelector
		 * 因为ImportBeanDefinitionRegistrar在扫描出来的时候已经被添加到一个list当中去了
		 */
		//bd 到 map 除却普通
		this.reader.loadBeanDefinitions(configClasses);
		alreadyParsed.addAll(configClasses);

		candidates.clear();
		//由于我们这里进行了扫描,把扫描出来的BeanDefinition注册给了factory
		//但是
		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();
	}
}

      查看第4步代码:ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory),再次会判断是否加了@Component、@Import、@Configuration、@ComponentScan等注解,如果加了Spring才会加到list中进行解析,如果不加就不进行解析,看代码块7

  代码块7.ConfigurationClassUtils#checkConfigurationClassCandidate方法

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...
		//1. 如果BeanDefinition 是 AnnotatedBeanDefinition的实例,并且className 和 BeanDefinition中 的元数据 的类名相同
		// 则直接从BeanDefinition 获得Metadata
		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.
		//2. 如果BeanDefinition 是 AbstractBeanDefinition的实例,并且beanDef 有 beanClass 属性存在
		//则实例化StandardAnnotationMetadata
		Class<?> beanClass = ((AbstractBeanDefinition) beanDef).getBeanClass();
		metadata = new StandardAnnotationMetadata(beanClass, true);
	}
	else {
		try {
			MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(className);
			metadata = metadataReader.getAnnotationMetadata();
		}
		catch (IOException ex) {
			return false;
		}
	}

	//3. 判断当前这个bd中存在的类是不是加了@Configruation注解
	//如果存在则spring认为他是一个全注解的类
	if (isFullConfigurationCandidate(metadata)) {
		//如果存在Configuration 注解,则为BeanDefinition 设置configurationClass属性为full
		beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_FULL);
	}
	//4. 判断是否加了以下注解,摘录isLiteConfigurationCandidate的源码
	//     candidateIndicators.add(Component.class.getName());
	//		candidateIndicators.add(ComponentScan.class.getName());
	//		candidateIndicators.add(Import.class.getName());
	//		candidateIndicators.add(ImportResource.class.getName());
	//如果不存在Configuration注解,spring则认为是一个部分注解类
	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;
}

        首先获取类上面的注解信息,然后判断如果加了@Configuration注解,则给beanDefinition的CONFIGURATION_CLASS_ATTRIBUTE属性设为full,如果加了@Component、@ComponentScan、@Import、@ImportResource,则给beanDefinition的CONFIGURATION_CLASS_ATTRIBUTE属性设为lite。

            

     会在第3步和第4步进行full和lite的判断,看代码块8

  代码块8. ConfigurationClassUtils#isFullConfigurationCandidate方法和ConfigurationClassUtils#isLiteConfigurationCandidate方法

    

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注解后,其CONFIGURATION_CLASS_ATTRIBUTE属性设为full,其他的加了@Component、@ComponentScan、@Import、@ImportResource,则给beanDefinition的CONFIGURATION_CLASS_ATTRIBUTE属性设为lite。

     这样设置了有什么用?就只是这个不一样就会造成很大不同吗?这个后面再说,现在我们说完了代码块4中的 invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry),该方法是将普通注解类转换成beanDefinition对象,并对标有@Configuration注解的类使用full进行标记。关于invokeBeanFactoryPostProcessors(registryProcessors, beanFactory)在下篇文章中进行源码分析,其就是根据CONFIGURATION_CLASS_ATTRIBUTE的值是否为full,进行增强,请大家前往Spring中@Configuration源码深度解析(二)继续学习@Configuration源码深度解析。

发布了227 篇原创文章 · 获赞 34 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/qq_35634181/article/details/104062321