ConfigurationClassPostProcessor浅析

<context:annotation-config/> 元素隐式注册以下post-processors:

  • ConfigurationClassPostProcessor
  • AutowiredAnnotationBeanPostProcessor
  • CommonAnnotationBeanPostProcessor
  • PersistenceAnnotationBeanPostProcessor
  • EventListenerMethodProcessor

注意:使用<context:component-scan/>隐式启用了<context:annotation-config/>功能。在使用<context:component-scan/>时,则通常不需要使用<context:annotation-config/>元素。

ConfigurationClassPostProcessor实现了BeanDefinitionRegistryPostProcessor。BeanDefinitionRegistryPostProcessor继承了BeanFactoryPostProcessor,BeanFactoryPostProcessor用于配置@Configuration类的引导处理。

获取ConfigurationClassPostProcessor的beanName

String[] postProcessorNames =
					beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);

通过上面的代码获取了一个集合,其中包含一个beanName:org.springframework.context.annotation.internalConfigurationAnnotationProcessor,实际上他就是ConfigurationClassPostProcessor对应的beanName。

根据beanName从beanFactory获取bean对象

合并beanDefinition

根据beanName从beanFactory的mergedBeanDefinitions集合中获取beanDefinition,然后在现有对象中从新克隆一个新的对象,没有scope属性默认设置为“singleton”,覆盖原来mergedBeanDefinitions,beanName对应的value。然后把beanDefinition返回。

bean的创建和初始化bean

合并beanDefinition时设置了scope为singleton,beanDefinition中只是获取了bean对应类的信息。

// Create bean instance.
if (mbd.isSingleton()) {
	sharedInstance = getSingleton(beanName, () -> {
		try {
			return createBean(beanName, mbd, args);
		}
		catch (BeansException ex) {
			// Explicitly remove instance from singleton cache: It might have been put there
			// eagerly by the creation process, to allow for circular reference resolution.
			// Also remove any beans that received a temporary reference to the bean.
			destroySingleton(beanName);
			throw ex;
		}
	});
	beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}

在这里插入图片描述
先是通过SimpleInstantiationStrategy创建bean对象,然后在初始化bean。

postProcessBeanDefinitionRegistry

通过执行ConfigurationClassPostProcessor的postProcessBeanDefinitionRegistry方法获取beanFactory(DefaultListableBeanFactory)中beanDefinition对应的类标注了@Configuration注解并且符合“full”和“lite”模式的beanDefinition,然后对beanDefinition根据“org.springframework.context.annotation.ConfigurationClassPostProcessor.order”属性排序。

  • 类标注了@Configuration注解的且属性proxyBeanMethods = true(proxyBeanMethods 默认为true),则设置beanDefinition的属性“org.springframework.context.annotation.ConfigurationClassPostProcessor.configurationClass”,为“full”,对没有标注@Configuration注解但标注了@Component、@ComponentScan、@Import、@ImportResource等设置为lite“”
  • 有@Order的注解的则设置beanDefinition的属性“org.springframework.context.annotation.ConfigurationClassPostProcessor.order

解析每个@Configuration类

  • 根据beanDefinittion的类全称获取对应的resource(ClassPathResource)
  • 创建SimpleMetadataReader对象,把resource, classLoader(ParallelWebappClassLoader)作为构造参数,通过ClassReader根据类路径读取类的信息,然后把类的相关的信息作为构造参数,创建SimpleAnootationMetadata对象。
  • 在metadatdaReaderCache缓存类的resource对应的metadataReader(SimpleMetadataReader)对象
  • 创建SourceClass对象,指定属性metadata为对应类的SimpleAnnotationMetadata对象
  • 执行ConfigurationClassParser的processConfigurationClass方法,解析标注@Configuration类中所有符合条件的类,把它们加载到ConfigurationClassParser的configurationClasses属性中。

在这里插入图片描述

loadBeanDefinitions

  • 判断ConfigurationClass来源是被标注@Import注解,还是方法上标注了@Bean注解。如果是@Import则创建 AnnotatedGenericBeanDefinition对象,然后获取ConfigurationClass对应的beanName,把这个两个对象作为构造参数创建BeanDefinitionHolder对象注册到beanFactory(DefaultListableBeanFactory)的beanDefinitionMap集合中。如果是@Bean则创建ConfigurationClassBeanDefinition对象然后把该对象注册在beanFactory的beanDefinitionMap集合中。
  • 对ImportedResources处理loadBeanDefinitionsFromImportedResources(configClass.getImportedResources());
  • 对ImportBeanDefinitionRegistrars处理loadBeanDefinitionsFromRegistrars(configClass.getImportBeanDefinitionRegistrars());

注册ImportRegistry

将ImportRegistry注册为一个bean,以便支持ImportAware @Configuration类

清空metadataReaderFactory

metadataReaderFactory包含了所有加载的类信息

if (this.metadataReaderFactory instanceof CachingMetadataReaderFactory) {
	// Clear cache in externally provided MetadataReaderFactory; this is a no-op
	// for a shared cache since it'll be cleared by the ApplicationContext.
	((CachingMetadataReaderFactory) this.metadataReaderFactory).clearCache();
}

postProcessBeanFactory

  • 获取beanFactory中bean名称定义集合(beanDefinitionNames),然后进行遍历根据beanName获取BeanDefinition中属性“org.springframework.context.annotation.ConfigurationClassUtils.configurationClass”值为“full”的beanDefinition集合。
  • 遍历上面的BeanDefinition集合设置属性“org.springframework.aop.framework.autoproxy.preserveTargetClass”为true
  • 使用ConfigurationClassEnhancer通过CGLIB生成beanDefinition类的enhancedClass(增强类)。增强类设置了父类为beanDefinition自己,设置实现了EnhancedConfiguration.class,设置用于生成器创建字节码的策略为BeanFactoryAwareGeneratorStrategy,设置callbackFilter,设置callbackType
  • 设置beanDefinition的beanClass为增强类
  • 缓存ConfigurationClassPostProcessor内部的静态类ImportAwareBeanPostProcessor到beanFactory的beanPostProcessors集合中

从spring项目启动ConfigurationClassPostProcessor被创建成单例然后跟踪代码简单记录ConfigurationClassPostProcessor做了哪些工作。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值