目录
1.ClassPathScanningCandidateComponentProvider
2.ClassPathBeanDefinitionScanner
0. 前述
ClassPathBeanDefinitionScanner的主要作用有两个:
- 扫描类路径下的候选Component,构造BeanDefinition对象(实际为ScannedGenericBeanDefinition)
- 利用BeanDefinitionRegister注册BeanDefinition到bean工厂中;
A bean definition scanner that detects bean candidates on the classpath,
registering corresponding bean definitions with a given registry ({@code BeanFactory} or {@code ApplicationContext}).
类图如下:
下面分别介绍下涉及的几个Class的作用
1.ClassPathScanningCandidateComponentProvider
ClassPathScanningCandidateComponentProvider是一个抽象类,实现EnvironmentCapable和ResourceLoaderAware接口,包含的主要成员变量有:ConditionEvaluator、ResourcePatternResolver、MetadataReaderFactory,同时依赖TypeFilter
/**
* A component provider that scans the classpath from a base package. It then
* applies exclude and include filters to the resulting classes to find candidates.
*
* <p>This implementation is based on Spring's
* {@link org.springframework.core.type.classreading.MetadataReader MetadataReader}
* facility, backed by an ASM {@link org.springframework.asm.ClassReader ClassReader}.*/
1.1 TypeFilter
TypeFilter主要用于过滤满足条件的BeanDefinition
1.2 ConditionEvaluator
主要用于Conditional注解的处理,仅当条件满足时才会注册bean
1.3 MetadataReaderFactory
MetadataReaderFactory利用工厂方法模式提供创建MetadataReader的接口,实现类有SimpleMetadataReaderFactory、CachingMetadataReaderFactory
其中CachingMetadataReaderFactory提供了对每个.class 文件缓存MetadataReader实例;
Factory interface for {@link MetadataReader} instances.
Allows for caching a MetadataReader per original resource.
关联类图如下:
2.ClassPathBeanDefinitionScanner
ClassPathBeanDefinitionScanner主要干了两件事:
-
扫描类路径下的候选BeanDefinition
-
将BeanDefinition注册到BeanDefinitionRegister中
/**
* A bean definition scanner that detects bean candidates on the classpath,
* registering corresponding bean definitions with a given registry ({@code BeanFactory} or {@code ApplicationContext}).
*/
类图如下:
/**
* Perform a scan within the specified base packages,
* returning the registered bean definitions.
* <p>This method does <i>not</i> register an annotation config processor
* but rather leaves this up to the caller.
* @param basePackages the packages to check for annotated classes
* @return set of beans registered if any for tooling registration purposes (never {@code null})
*/
protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
Assert.notEmpty(basePackages, "At least one base package must be specified");
Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<BeanDefinitionHolder>();
for (String basePackage : basePackages) {
Set<BeanDefinition> candidates = findCandidateComponents(basePackage);
for (BeanDefinition candidate : candidates) {
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) {
AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);
}
if (checkCandidate(beanName, candidate)) {
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
definitionHolder =
AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
beanDefinitions.add(definitionHolder);
registerBeanDefinition(definitionHolder, this.registry);
}
}
}
return beanDefinitions;
}
2.1 ScopeMetadataResolver
主要用于处理@Scope注解,提供获取ScopeMetaData对象的能力,并且基于代理模式创建代理类;
2.2 BeanNameGenerator
主要用于产生beanName
2.3 BeanDefinitionRegistry
注册BeanDefinition到容器中