publicclassComponentScanBeanDefinitionParserimplementsBeanDefinitionParser{publicBeanDefinitionparse(Elementelement,ParserContextparserContext){// 获取base-package属性StringbasePackage=element.getAttribute(BASE_PACKAGE_ATTRIBUTE);basePackage=parserContext.getReaderContext().getEnvironment().resolvePlaceholders(basePackage);String[]basePackages=StringUtils.tokenizeToStringArray(basePackage,ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);// Actually scan for bean definitions and register them.ClassPathBeanDefinitionScannerscanner=configureScanner(parserContext,element);// TODO 重点:这里执行了具体的解析逻辑。Set<BeanDefinitionHolder>beanDefinitions=scanner.doScan(basePackages);registerComponents(parserContext.getReaderContext(),beanDefinitions,element);returnnull;}}
publicclassComponentScanBeanDefinitionParserimplementsBeanDefinitionParser{protectedSet<BeanDefinitionHolder>doScan(String...basePackages){Assert.notEmpty(basePackages,"At least one base package must be specified");// 用来装所有扫描到的类的BeanDefinition对象。Set<BeanDefinitionHolder>beanDefinitions=newLinkedHashSet<>();for(StringbasePackage:basePackages){// TODO 重点看:查找候选组件,封装成BeanDefinition。Set<BeanDefinition>candidates=findCandidateComponents(basePackage);for(BeanDefinitioncandidate:candidates){// 获取到ScopeMetadata,如果类中有@Scope注解,则会将值封装到这个实例中。然后设置到BeanDefinition中。ScopeMetadatascopeMetadata=this.scopeMetadataResolver.resolveScopeMetadata(candidate);candidate.setScope(scopeMetadata.getScopeName());StringbeanName=this.beanNameGenerator.generateBeanName(candidate,this.registry);// 对不同类型的BeanDefinition做不同的处理。if(candidateinstanceofAbstractBeanDefinition){postProcessBeanDefinition((AbstractBeanDefinition)candidate,beanName);}// 对不同类型的BeanDefinition做不同的处理,@Lazy、@DependOn等注解信息封装就是在这里设置的。if(candidateinstanceofAnnotatedBeanDefinition){// 一些注解信息的封装AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition)candidate);}// 校验是否是需要实例化的BeanDefinition,如果为true,则将BeanDefinition包装成BeanDefinitionHolder(这个类里封装了实例名称、别名信息)if(checkCandidate(beanName,candidate)){BeanDefinitionHolderdefinitionHolder=newBeanDefinitionHolder(candidate,beanName);definitionHolder=AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata,definitionHolder,this.registry);beanDefinitions.add(definitionHolder);// 注册BeanDefinitionregisterBeanDefinition(definitionHolder,this.registry);}}}returnbeanDefinitions;}}
publicclassComponentScanBeanDefinitionParserimplementsBeanDefinitionParser{privateSet<BeanDefinition>scanCandidateComponents(StringbasePackage){Set<BeanDefinition>candidates=newLinkedHashSet<>();try{//根据路径扫描StringpackageSearchPath=ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX+resolveBasePackage(basePackage)+'/'+this.resourcePattern;// 获取指定包下匹配到的所有的资源对象。里面封装了InputStream,用来读取类文件。Resource[]resources=getResourcePatternResolver().getResources(packageSearchPath);booleantraceEnabled=logger.isTraceEnabled();booleandebugEnabled=logger.isDebugEnabled();for(Resourceresource:resources){if(traceEnabled){logger.trace("Scanning "+resource);}if(resource.isReadable()){try{// 封装成ScannedGenericBeanDefinition,这里封装了包下所有的类信息MetadataReadermetadataReader=getMetadataReaderFactory().getMetadataReader(resource);if(isCandidateComponent(metadataReader)){// 创建BeanDefinition对象,将ScannedGenericBeanDefinitionsbd=newScannedGenericBeanDefinition(metadataReader);sbd.setResource(resource);sbd.setSource(resource);// 判断是否是候选组件,如果是,就添加BeanDefinition对象if(isCandidateComponent(sbd)){if(debugEnabled){logger.debug("Identified candidate component class: "+resource);}candidates.add(sbd);}else{if(debugEnabled){logger.debug("Ignored because not a concrete top-level class: "+resource);}}}else{if(traceEnabled){logger.trace("Ignored because not matching any filter: "+resource);}}}catch(Throwableex){thrownewBeanDefinitionStoreException("Failed to read candidate component class: "+resource,ex);}}else{if(traceEnabled){logger.trace("Ignored because not readable: "+resource);}}}}catch(IOExceptionex){thrownewBeanDefinitionStoreException("I/O failure during classpath scanning",ex);}returncandidates;}}
publicclassAnnotationConfigBeanDefinitionParserimplementsBeanDefinitionParser{publicBeanDefinitionparse(Elementelement,ParserContextparserContext){Objectsource=parserContext.extractSource(element);// TODO 重点看下,逻辑相对简单,注册一些内置注解解析支持Set<BeanDefinitionHolder>processorDefinitions=AnnotationConfigUtils.registerAnnotationConfigProcessors(parserContext.getRegistry(),source);// 省略...returnnull;}}