准备
AnnotationConfigUtils类
public static final String CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME =
"org.springframework.context.annotation.internalConfigurationAnnotationProcessor";
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
BeanDefinitionRegistry registry, @Nullable Object source) {
.........................省略若干代码........................
// 注册内部管理的用于处理@configuration注解的后置处理器的bean
if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
def.setSource(source);
// 注册BeanDefinition到注册表中 。ConfigurationClassPostProcessor到注册表中(以后可以实例化了)
beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
}
.........................省略若干代码...........................
return beanDefs;
}
==========================注解工具注册====================
调用registerAnnotationConfigProcessors(..)注册bd
// 根据条件,选择注册bean的定义信息
1. ConfigurationClassPostProcessor(bfpp)
2. AutowiredAnnotationBeanPostProcessor(bpp)
3. CommonAnnotationBeanPostProcessor(bpp)
4. EventListenerMethodProcessor(bfpp)
5. DefaultEventListenerFactory 等
在下面三个地方调用了:
1.
//registerBeanDefinitionParser("annotation-config", new //AnnotationConfigBeanDefinitionParser());
AnnotationConfigBeanDefinitionParser.java#parse{
//注册注解配置处理器 bean信息
Set<BeanDefinitionHolder> processorDefinitions =
//注册bfpp和bpp
AnnotationConfigUtils.registerAnnotationConfigProcessors(parserContext.getRegistry(), source);
}
//根据标签解析。注册解析器
registerBeanDefinitionParser("annotation-config", new AnnotationConfigBeanDefinitionParser());
2.
//处理 <component:scan base-package.. 等xml 配置
// registerBeanDefinitionParser("component-scan", new //ComponentScanBeanDefinitionParser());
ComponentScanBeanDefinitionParser.java#parse{
ClassPathBeanDefinitionScanner#doScan();
// 把扫描到的bd放进容器
// 注册系统bd信息
AnnotationConfigUtils.registerAnnotationConfigProcessors(..)
}
3.本类 registerAnnotationConfigProcessors(BeanDefinitionRegistry registry) {
registerAnnotationConfigProcessors(registry, null);
}
3.1 使用注解启动的时候,使用的。AnnotationConfigApplicationContext启动的
//在构造方法中调用了
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
// 。。。
this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}
===========================
**总结**:上面的第一和第二,是处理xml配置(component-scan和annotation-config)的时候,注册bfpp等定义信息的。第三种是注解启动时候注册各种bd信息的。
在AnnotationConfigBeanDefinitionParser
和ComponentScanBeanDefinitionParser
的parse()中;AnnotatedBeanDefinitionReader
构造方法中 等地方有调用
分析
- refresh()->
- invokeBeanFactoryPostProcessors(beanFactory)->
- 找到所有符合规则的名字。String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
- // 遍历处理所有符合规则的postProcessorNames,并生成对象,放进list中。(重点核心org.springframework.context.annotation.internalConfigurationAnnotationProcessor生成ConfigurationClassPostProcessor对象,这个beanName在上文准备阶段),currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
- 执行bfpp。 invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
- 调用ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry()
===》 postProcessor.postProcessBeanDefinitionRegistry(registry);
=====》ConfigurationClassPostProcessor.java#processConfigBeanDefinitions(){
//创建对象,调用解析方法
ConfigurationClassParser parser = new …
parser.parse(candidates);
}
=======>ConfigurationClassParser.java#parse(…){
//根据不同的类型,调用重载的parse方法
}
以注解为例子
->parse()
–>processConfigurationClass()
—>doProcessConfigurationClass(){
//1. 递归处理内部类,符合条件的加入到候选。遍历处理
2. 处理@PropertySource 注解
3. 处理处理@ComponentScan或者@ComponentScans注解,通过ComponentScanAnnotationParser#parse(…),进而调用ClassPathBeanDefinitionScanner#doScan(…),解析的是@Component及其子类,解析到了所有的scannedBeanDefinitions,判断是,是不是配置类,是配置类,再递归处理
4. 处理@Import注解
5. 处理@ImportResource注解
6. 处理@Bean注解的方法
7. 处理接口,jdk8支持接口@Bean注解
}
处理注解的核心方法
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);
}
// Process any @PropertySource annotations
// 如果配置类上加了@PropertySource注解,那么就解析加载properties文件,并将属性添加到spring上下文中。@Value(${})
// 加到beanFactory中。实例化的时候才会赋值
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");
}
}
// Process any @ComponentScan annotations
// 处理@ComponentScan或者@ComponentScans注解,并将扫描包下的所有bean转换成填充后的ConfigurationClass
// 此处就是将自定义的bean加载到IOC容器,因为扫描到的类可能也添加了@ComponentScan和@ComponentScans注解,因此需要进行递归解析
Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable(
sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class);
if (!componentScans.isEmpty() &&
!this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) {
for (AnnotationAttributes componentScan : componentScans) {
//再创建部件扫描解析器
//*********ClassPathBeanDefinitionScanner 类******
Set<BeanDefinitionHolder> scannedBeanDefinitions =
this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());
// Check the set of scanned definitions for any further config
for (BeanDefinitionHolder holder : scannedBeanDefinitions) {
BeanDefinition bdCand = holder.getBeanDefinition().getOriginatingBeanDefinition();
if (bdCand == null) {
bdCand = holder.getBeanDefinition();
}
// 判断是否是一个配置类,并设置full或lite属性
if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) {
// 通过递归方法进行解析
parse(bdCand.getBeanClassName(), holder.getBeanName());
}
}
}
}
// Process any @Import annotations
// 处理 @Import注解。查找所有的@import注解,找到注解中的类并实例化。直接处理或者加入handler中
processImports(configClass, sourceClass, getImports(sourceClass), filter, true);
// Process any @ImportResource annotations
// 处理@ImportResource注解,导入spring的配置文件.
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);
}
}
// Process individual @Bean methods
// 处理加了@Bean注解的方法,将@Bean方法转化为BeanMethod对象,保存再集合中
Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass);
for (MethodMetadata methodMetadata : beanMethods) {
configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
}
// Process default methods on interfaces
// 处理接口的默认方法实现,从jdk8开始,接口中的方法可以有自己的默认实现,因此如果这个接口的方法加了@Bean注解,也需要被解析
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;
}