【Spring生命周期核心底层源码之剖析】
- 互联网
- 2025-08-13 08:06:02

文章目录 一、Spring生命周期核心底层源码剖析—扫描1.1、Spring底层扫描机制doScan方法源码剖析 一、Spring生命周期核心底层源码剖析—扫描 1.1、Spring底层扫描机制doScan方法源码剖析
其源代码如下:
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) { Set<BeanDefinition> candidates = findCandidateComponents(basePackage); //遍历其获取到的BeanDefinition对象 for (BeanDefinition candidate : candidates) { //为其BeanDefinition对象进行属性赋值,例如scope,beanName等 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); } //判断当前的bean是否已经在Spring容器中存在,存在需封装为BeanDefinitionHolder对象 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; }1、其主要是通过传入的包路径进行资源加载,加载时方法为上诉代码的for循环下的第一行代码的findCandidateComponents()方法,可以详细看此方法,是如何加载资源的,其方法代码如下(具体说明以及解析过程可参考注释):
public Set<BeanDefinition> findCandidateComponents(String basePackage) { //此处主要是判断项目是否配置了相关的bean文件,若有,就不需要再逐个类进行扫描+判断是否为Bean if (this ponentsIndex != null && indexSupportsIncludeFilters()) { return addCandidateComponentsFromIndex(this ponentsIndex, basePackage); } //大部分的业务都会走如下方法 else { return scanCandidateComponents(basePackage); } } //scanCandidateComponents方法具体实现为 private Set<BeanDefinition> scanCandidateComponents(String basePackage) { Set<BeanDefinition> candidates = new LinkedHashSet<>(); try { //1、资源路径组装解析 String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX + resolveBasePackage(basePackage) + '/' + this.resourcePattern; //2、利用类元数据读取器读取器路径下包含的资源数据 Resource[] resources = getResourcePatternResolver().getResources(packageSearchPath); boolean traceEnabled = logger.isTraceEnabled(); boolean debugEnabled = logger.isDebugEnabled(); //3、遍历类元数据读取器获取到的资源数据(class资源文件数据) for (Resource resource : resources) { if (traceEnabled) { logger.trace("Scanning " + resource); } try { //4、获取当前类元数据(calss)具体资源信息 MetadataReader metadataReader = getMetadataReaderFactory().getMetadataReader(resource); //5、判断当前的类(class)上包含的是否包含排除注解excludeFilters以及非排除注解includeFilters,以及是否包含相关的条件注解Conditional if (isCandidateComponent(metadataReader)) { //6、创建一个BeanDefinition对象,用于封装其类特征信息,例如:beanClass、scope、lazyInit等属性 ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader); //7、将类资源数据加入到BeanDefinition中 sbd.setSource(resource); //8、判断当前的类资源是否是独立的(例如是否是内部类等),除此歪,需要判断其是否为接口或者抽象类,如果是抽象类,那类中必须有被Lookup注解的方法,否则不会被当做bean if (isCandidateComponent(sbd)) { if (debugEnabled) { logger.debug("Identified candidate component class: " + resource); } //9、将封装好的BeanDefinition对象加入到返回的集合Set中 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 (FileNotFoundException ex) { if (traceEnabled) { logger.trace("Ignored non-readable " + resource + ": " + ex.getMessage()); } } 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; }【Spring生命周期核心底层源码之剖析】由讯客互联互联网栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“【Spring生命周期核心底层源码之剖析】”