代码流程
springApplication load方法初始化BeanDefinitionLoader,并执行loader方法。
BeanDefinitionLoader scanner指定的是ClassPathBeanDefinitionScanner,loader方法执行的是ClassPathBeanDefinitionScanner的scan方法。
ClassPathBeanDefinitionScanner doScan调用ClassPathScanningCandidateComponentProvider的scanCandidateComponents方法加载扫描路径下的class文件,由metadataReaderFactory生成MetadataReader实体。
private Set<BeanDefinition> scanCandidateComponents(String basePackage) {
Set<BeanDefinition> candidates = new LinkedHashSet<>();
try {
String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +
resolveBasePackage(basePackage) + '/' + this.resourcePattern;
Resource[] resources = this.resourcePatternResolver.getResources(packageSearchPath);
for (Resource resource : resources) {
if (resource.isReadable()) {
try {
MetadataReader metadataReader = this.metadataReaderFactory.getMetadataReader(resource);
if (isCandidateComponent(metadataReader)) {
ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader);
sbd.setResource(resource);
sbd.setSource(resource);
if (isCandidateComponent(sbd)) {
if (debugEnabled) {
logger.debug("Identified candidate component class: " + resource);
}
candidates.add(sbd);
}
}
catch (Throwable ex) {
throw new BeanDefinitionStoreException(
"Failed to read candidate component class: " + resource, ex);
}
}
}
}
catch (IOException ex) {
throw new BeanDefinitionStoreException("I/O failure during classpath scanning", ex);
}
return candidates;
}
SimpleMetadataReader利用asm的ClassReader解析class文件,将class的注解配置信息读取到AnnotationMetadataReadingVisitor中。
至此ClassPathBeanDefinitionScanner完成scan package下class的注解解析。