其他分享
首页 > 其他分享> > BeanDefinition扫描

BeanDefinition扫描

作者:互联网

执行流程

  1. 根据classpath:* + 包名获取所有.class文件
  2. 遍历Resouce资源文件。
  3. 判断当前resouce文件所指的类是否拥有component注解,也就是判断该bean是否要扫描到spring容器中。
  4. 构建beanDefiniation,并将资源和类全限定包名设置上去。
  5. 在上一步仅仅是构造了BeanDefiniation并将bean全限定名称设置上去,但是类是否为单例、是否懒加载等等还没有设置,所以接下来要设置其余BeanDefiniation。
  6. 遍历BeanDefinitionList,并设置scope。
  7. 获取并设置beanName。
  8. 设置beanDefiniation默认值。
  9. 解析 @Lazy、@DependsOn、@Role和@Description注解
  10. 检查bean是否注册过,如果没注册过则对bean进行注册。

AnnotationConfigApplicationContext

首先AnnotationConfigApplicationContext新建了两个对象,分别是BeanDefinition读取器和扫描器,Bean是由扫描器来进行扫描的,先从这个类看起,spring是怎样完成扫描操作的。
image

包扫描

ClassPathBeanDefinitionScanner中有个scan方法用于进行包扫描的,在这个方法中有个doScan方法用于完成扫描逻辑,进入这个方法看一下。
image
主要注释已经写完了,通过扫描将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