<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做了哪些工作。