Spring IOC源码解析
2022-04-19 17:20:19 11 举报
认购流程
作者其他创作
大纲/内容
添加不包含过滤(当前配置类名)
refresh();
调用到目前为止处理的所有处理器的postProcessBeanFactory回调
@Bean和@Import类型,是在这里才注册bean定义的parse()方法中只是解析
ComponentScanAnnotationParser.parse(...)
②
First,调用实现了 PriorityOrdered接口的BeanDefinitionRegistryPostProcessor类型的处理器(集合)
if (beanFactory instanceof BeanDefinitionRegistry)DefaultListableBeanFactory 实现了当前bean定义注册接口,所以走if 逻辑
registerBeanDefinition(span style=\"font-size: inherit;\
for (SourceClass candidate : importCandidates)
资料不齐
ImportBeanDefinitionRegistrar类型
解析 default方法(接口) 忽略
合同移交
解析 @ComponentScan注解
parse(Set<BeanDefinitionHolder> configCandidates)
ImportSelector类型
调用上下文中bean工厂后置处理器
挞定函
scanner.doScan(StringUtils.toStringArray(basePackages))
解析 @Import注解
未跳过,真正执行 注解配置解析
按期签约
ConfigurationClassParser parser = new ConfigurationClassParser( ... )
到期楼款
上述方法获取来源类数据 Collection importCandidates
导入: if (configClass.isImported())
遍历 candidates1、生成beanName2、检验(是否注册过 - 类型、来源、相等性) 3、构建持有器,执行注册
创建扫描器,根据参数 useDefaultFilters决定是否添加默认过滤器(@Component 等)接下来,以配置源属性数据进行赋值
@ComponentScan 的basePackages是字符串数组类型接下来就是解析每个包扫描路径(匹配过滤器)
针对上述方法返回的 bean定义持有器集合,遍历,解析原因:假设上述集合中存在一个@Configuration配置类,代码进行到这里时,仅仅说明当前配置类已经完成了注册,但是不代表它内部的@Bean方法和 import注解也进行了解析
同上注意:当前处理的是 上述Next处理中重写方法中注册的当前类型对象(泛指A对象) 及 A对象中注册的当前类型对象(递归)或 代码中显式注入的实例对象(未实现 Ordered接口)及 其重写方法中注册的当前类型对象(递归)
遍历注册表中所有的bean定义对象,筛选出 的自定义配置类,并加入到候选解析集合如果,候选解析集合不为空,创建解析器
委托调用
资料审核
ConfigurationClassParser
this.reader.loadBeanDefinitions(configClasses)
遍历set集合,根据bean定义类型执行解析这里分析 AnnotatedBeanDefinition类型的,因为步骤②加载配置源时,创建的就是当前类型的bean定义对象
else
ConfigurationClassBeanDefinitionReader.loadBeanDefinitions(Set<ConfigurationClass> configurationModel)
校验
解析注解信息(递归父注解)getImports(sourceClass)
在途跟踪
configurationClasses属性实际上是 LinkedHashMap结构,put方法调用的是其父类 HashMap的。ConfigurationClass重写了hashCode和equals方法(依据 getMetadata().getClassName() 配置源类名)如果 existingClass不为空,说明之前已经加载过了 。那么接下来就是判断 existingClass 和待解析配置源configClass的类型了(是否被导入① 或 bean定义查找② )处理优先级:② > ①如果 configClass是②类型,则删除existingClass(无论是否②类型),执行后续解析;如果 existingClass是①类型,合并configClass的导入源(外部类) ,再返回,否则不做任何处理直接返回;当然,如果 existingClass为空,执行解析。
@OverridepostProcessBeanDefinitionRegistry(BeanDefinitionRegistry)
资料齐全
特殊申请请示(资料补齐签约)
如果当前配置类被@Component所注解,则递归地处理(嵌套的)内部类
beanFactory.getBeanNamesForType(span style=\"font-size: inherit;\
重点:ConfigurationClassPostProcessor
循环解析每个配置源
有一点需要说明,真正在扫描配置类时使用的ClassPathBeanDefinitionScanner 都是新创建的,并不会使用在创建applicationContext时内置的scanner。那么这个scanner是怎么使用的呢?(编程式扫描)AnnotationConfigApplicationContext ctx = new ...();ctx.refresh();ctx.scan(\"com.tuling.springtest.ioc.beanFactoryPostProcessor\");ctx.getBean(TulingLog.class);
invokeBeanFactoryPostProcessors(beanFactory);
processConfigurationClass(ConfigurationClass configClass)
loadBeanDefinitionsForBeanMethod(beanMethod)
解析 @ImportResource注解 忽略
添加
上述方法的第二个参数是BeanFactoryPostProcessor类型的集合,循环执行如果当前后置处理器是 BeanDefinitionRegistryPostProcessor类型的,调用其注册方法,并添加到 registryProcessors集合如果不是,直接添加到 regularPostProcessors集合
递归处理
@Bean: 遍历 configClass.getBeanMethods()附:注册别名
执行解析
遍历,判断类型
签约交款
逾期签约
Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass)
遍历 ConfigurationClass 注册类本身及其所有@bean方法的bean定义
@Import中的 ImportBeanDefinitionRegistrar类型
loadBeanDefinitionsFromImportedResources(configClass.getImportedResources())
do... 真正干事的
催款函
最后
loadBeanDefinitionsForConfigurationClass( ... )
根据@Conditional 注释判断一个项目是否应该被跳过
检索所有@Bean方法的元数据
系统转签
processConfigBeanDefinitions(registry)
不予签约
签约环节
this.conditionEvaluator.shouldSkip(...)
registerBeanDefinitionForImportedConfigurationClass(configClass)
Set<BeanDefinition> candidates = findCandidateComponents(basePackage)
return null;
解析 @PropertySource注解 忽略
loadBeanDefinitionsFromRegistrars(configClass.getImportBeanDefinitionRegistrars())
售后审核
@ImportResource 忽略
ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(...)
从 beanFactory中筛选出 BeanDefinitionRegistryPostProcessor类型的 beanName集合注意:虽然beanFactory中记录了多个bean定义(步骤①中 初始化reader 和 注册自定义配置类),但是首次筛选时,符合类型条件的只有 ConfigurationClassPostProcessor
补齐后转签
解析 @Bean注解
过滤
processImports( ... )
processConfigurationClass(candidate.asConfigClass(configClass))
parser.parse(candidates)
解析 超类(return) 忽略
默认会注册三个过滤器,其中重要是 Component类型
解析注册的bean定义是否被 @Configuration 或 @Component 标注了
加载自定义配置至注册表
configClass.addImportBeanDefinitionRegistrar(...)
按揭审批
遍历集合
①
ConfigurationClass existingClass = this.configurationClasses.get(configClass)
认购环节
this.includeFilters.add(new AnnotationTypeFilter(Component.class));
合同用印
收藏
0 条评论
下一页