Spring源码扫描逻辑

1、扫描

先进入ClassPathBeanDefinitionScanner.java文件中
在这里插入图片描述
找到这个scan()方法,其中扫描逻辑在doScan方法中。

2、根据包路径扫描

在这里插入图片描述
在查找符合的BeanDefinition的逻辑中,会区分是否配置加快扫描的文件,如果配置了,只会扫描配置了的路径下的文件,加快扫描速度。如果没有配置,则根据包路径,扫描下面的每个文件(绝大部分都是这个情况)。
在这里插入图片描述
进入scanCandidateComponents方法中,根据包路径,组装类的全局路径,借助文件读取器,将该路径下的所有资源都读取出来。

String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +
					resolveBasePackage(basePackage) + '/' + this.resourcePattern;
			// 根据文件读取器,将此路径下的class文件都找出来
			Resource[] resources = getResourcePatternResolver().getResources(packageSearchPath);

3、通过ASM技术,读取该资源下的文件信息,获取到元数据。

**isCandidateComponent(metadataReader)**该方法是用来判断是否符合配置了TypeFilter参数。
在这里插入图片描述

4、接下来生成BeanDefinition,设置元数据信息。并且判断这个BeanDefinition是否符合条件,进入isCandidateComponent此方法中。

protected boolean isCandidateComponent(AnnotatedBeanDefinition beanDefinition) {
		AnnotationMetadata metadata = beanDefinition.getMetadata();
		// isIndependent 是否为内部类
		// isConcrete 是否为接口、是否为抽象类
		// metadata.isAbstract() && metadata.hasAnnotatedMethods(Lookup.class.getName()))) 是抽象类,但这个类上有LookUp接口
		return (metadata.isIndependent() && (metadata.isConcrete() ||
				(metadata.isAbstract() && metadata.hasAnnotatedMethods(Lookup.class.getName()))));
	}

找出该包路径下所有的BeanDefinition后,需要对这些进行属性填充了。

for (BeanDefinition candidate : candidates) {
				// 填充作用域
				ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);
				candidate.setScope(scopeMetadata.getScopeName());
				// 生成BeanName
				String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);
				if (candidate instanceof AbstractBeanDefinition) {
					postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);
				}
				if (candidate instanceof AnnotatedBeanDefinition) {
					// 填充 是否为懒加载,填充scope作用域,填充是否存在依赖等
					AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);
				}
				// 判断BeanDefinition是否重复
				if (checkCandidate(beanName, candidate)) {
					BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
					definitionHolder =
							AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
					beanDefinitions.add(definitionHolder);
					registerBeanDefinition(definitionHolder, this.registry);
				}
			}
		}

其中checkCandidate做了进一步检查
在这里插入图片描述

5、注册BeanDefinition(将BeanDefinition设置到Map中)

在这里插入图片描述
到此,扫描逻辑基本结束。接下来将进行初始化的逻辑

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值