一、ClassPathBeanDefinitionScanner#doScan
protected SetdoScan(String... basePackages) { Assert.notEmpty(basePackages, "At least one base package must be specified"); Set beanDefinitions = new LinkedHashSet(); String[] var3 = basePackages; int var4 = basePackages.length; //扫描@ComponentScan包设置扫描包路径 for(int var5 = 0; var5 < var4; ++var5) { String basePackage = var3[var5]; //获取候选的BeanDefinition此时 Set candidates = this.findCandidateComponents(basePackage); Iterator var8 = candidates.iterator(); while(var8.hasNext()) { BeanDefinition candidate = (BeanDefinition)var8.next(); ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate); candidate.setScope(scopeMetadata.getScopeName()); String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry); if (candidate instanceof AbstractBeanDefinition) { //为beanDefinition设置InitMethod、DestroyMethod、LazyInit等属性 this.postProcessBeanDefinition((AbstractBeanDefinition)candidate, beanName); } if (candidate instanceof AnnotatedBeanDefinition) { //设置@Lazy @Primary @DependsOn @Role @Description属性 AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition)candidate); } //检查容器中是否存在相同名称的beanDefinition,存在则报错(特殊情况,spring存在注册同一个配置类,则beandefinition不会注册) if (this.checkCandidate(beanName, candidate)) { BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName); definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry); beanDefinitions.add(definitionHolder); this.registerBeanDefinition(definitionHolder, this.registry); } } } return beanDefinitions; }
二、获取候选的beandefinition,this.findCandidateComponents(basePackage)
public SetfindCandidateComponents(String basePackage) { LinkedHashSet candidates = new LinkedHashSet(); try { String packageSearchPath = "classpath*:" + this.resolveBasePackage(basePackage) + '/' + this.resourcePattern; //包下class对象都会解析成对应的resource对象文件对象 Resource[] resources = this.resourcePatternResolver.getResources(packageSearchPath); boolean traceEnabled = this.logger.isTraceEnabled(); boolean debugEnabled = this.logger.isDebugEnabled(); Resource[] var7 = resources; int var8 = resources.length; //遍历所有文件对象数组 for(int var9 = 0; var9 < var8; ++var9) { Resource resource = var7[var9]; if (traceEnabled) { this.logger.trace("Scanning " + resource); } if (resource.isReadable()) { try { //利用ASM技术把文件对象解析成元数据信息 MetadataReader metadataReader = this.metadataReaderFactory.getMetadataReader(resource); //解析是否包含Component注解,以及剔除excludeFilters配置的,includeFilters匹配则成功(new AnnotationTypeFilter(Component.class)),匹配通过继续筛选是否有Condition条件 if (this.isCandidateComponent(metadataReader)) { ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader); sbd.setResource(resource); sbd.setSource(resource); //判断当前对象是否顶级、静态内部类对象,非抽象类、非接口对象,若为抽象类(包含@Lookup注解)也通过;总结:顶级类、非接口抽象类、抽象类(必须包含@Lookup注解) if (this.isCandidateComponent((AnnotatedBeanDefinition)sbd)) { if (debugEnabled) { this.logger.debug("Identified candidate component class: " + resource); } //满足以上条件才能成为候选beanDefinition即真正的beandefinition candidates.add(sbd); } else if (debugEnabled) { this.logger.debug("Ignored because not a concrete top-level class: " + resource); } } else if (traceEnabled) { this.logger.trace("Ignored because not matching any filter: " + resource); } } catch (Throwable var13) { throw new BeanDefinitionStoreException("Failed to read candidate component class: " + resource, var13); } } else if (traceEnabled) { this.logger.trace("Ignored because not readable: " + resource); } } return candidates; } catch (IOException var14) { throw new BeanDefinitionStoreException("I/O failure during classpath scanning", var14); } }
三、this.isCandidateComponent
protected boolean isCandidateComponent(MetadataReader metadataReader) throws IOException {
//@ComponentScan中配置剔除条件过滤器
Iterator var2 = this.excludeFilters.iterator();
TypeFilter tf;
do {
if (!var2.hasNext()) {
//@ComponentScan中满足这些条件过滤器则通过,spring内置一个 this.includeFilters.add(new AnnotationTypeFilter(Component.class));
var2 = this.includeFilters.iterator();
do {
if (!var2.hasNext()) {
return false;
}
tf = (TypeFilter)var2.next();
} while(!tf.match(metadataReader, this.metadataReaderFactory));
//以上条件都满足看当前bean是否有@Condition注解上设置的条件继续看是否满足条件
return this.isConditionMatch(metadataReader);
}
tf = (TypeFilter)var2.next();
} while(!tf.match(metadataReader, this.metadataReaderFactory));
return false;
}
四、上面筛选出@Component的beandefinition此时还不能是真正的beandefition
必须满足一下条件才能成为真正的beandefinition
this.isCandidateComponent((AnnotatedBeanDefinition)sbd)
protected boolean isCandidateComponent(AnnotatedBeanDefinition beanDefinition) {
AnnotationMetadata metadata = beanDefinition.getMetadata();
//1、顶级类、静态内部类 2、非接口、非抽象类 3、抽象类(有@Lookup注解)
return metadata.isIndependent() && (metadata.isConcrete() || metadata.isAbstract() && metadata.hasAnnotatedMethods(Lookup.class.getName()));
}
五、总结
1、扫描@ComponentScan配置扫描包路径
2、扫描到class封装成Resource文件对象
3、遍历Resource数组对象,把Resource对象ASM技术封装成MetadataReader
4、MetadataReader对其进行筛选(配置的过滤器,默认 this.includeFilters.add(new AnnotationTypeFilter(Component.class))会去过滤Component注解的类,筛选类上是否有@Condtition注解的条件
5、a、顶级类、静态内部类、b、非接口、非抽象类、c、抽象类(包含@Lookup注解的类)满足以上45中才能BeanDefinition
6、为BeanDefinition设置@Lazy @Primary @DependsOn @Role @Description属性、设置InitMethod、DestroyMethod、LazyInit等属性
7、把BeanDefinition添加到map中,beanDefinitions.add(definitionHolder);



