BeanDefinition扫描
作者:互联网
执行流程
- 根据classpath:* + 包名获取所有.class文件
- 遍历Resouce资源文件。
- 判断当前resouce文件所指的类是否拥有component注解,也就是判断该bean是否要扫描到spring容器中。
- 构建beanDefiniation,并将资源和类全限定包名设置上去。
- 在上一步仅仅是构造了BeanDefiniation并将bean全限定名称设置上去,但是类是否为单例、是否懒加载等等还没有设置,所以接下来要设置其余BeanDefiniation。
- 遍历BeanDefinitionList,并设置scope。
- 获取并设置beanName。
- 设置beanDefiniation默认值。
- 解析 @Lazy、@DependsOn、@Role和@Description注解
- 检查bean是否注册过,如果没注册过则对bean进行注册。
AnnotationConfigApplicationContext
首先AnnotationConfigApplicationContext
新建了两个对象,分别是BeanDefinition
读取器和扫描器,Bean是由扫描器来进行扫描的,先从这个类看起,spring是怎样完成扫描操作的。
包扫描
在ClassPathBeanDefinitionScanner
中有个scan
方法用于进行包扫描的,在这个方法中有个doScan
方法用于完成扫描逻辑,进入这个方法看一下。
主要注释已经写完了,通过扫描将beanDefinitions
进行返回
protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
Assert.notEmpty(basePackages, "At least one base package must be specified");
Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<>();
for (String basePackage : basePackages) {
// 获取BeanDefinition,这里仅仅是将类名称获取到,是否单例 是否懒加载之类的参数还未获取,以下for循环就是获取这些参数的
Set<BeanDefinition> candidates = findCandidateComponents(basePackage);
for (BeanDefinition candidate : candidates) {
// 获取scope数据信息
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);
candidate.setScope(scopeMetadata.getScopeName());
String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);
if (candidate instanceof AbstractBeanDefinition) {
// 设置默认值和不知道干什么的方法
postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);
}
if (candidate instanceof AnnotatedBeanDefinition) {
// 解析 @Lazy、@DependsOn、@Role和@Description注解
AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);
}
// 检查bean是否被注册
if (checkCandidate(beanName, candidate)) {
// 构造一个BeanDefinitionHolder一,BeanDefinitionHolder中封装着beanName和BeanDefinition
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
// 这个先忽略
definitionHolder =
AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
beanDefinitions.add(definitionHolder);
// 注册beanDefinition到map中
registerBeanDefinition(definitionHolder, this.registry);
}
}
}
return beanDefinitions;
}
标签:candidate,definitionHolder,beanName,扫描,bean,BeanDefinition 来源: https://www.cnblogs.com/lyraHeartstrings/p/16335555.html