> 文章列表 > (一)Spring源码——注册BeanDefinition

(一)Spring源码——注册BeanDefinition

(一)Spring源码——注册BeanDefinition


typora-copy-images-to: imgs

1. 程序入口

程序入口:

public class MainTest {public static void main(String[] args) {AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);}
}

2. AnnotationConfigApplicationContext构造

通过点进 AnnotationConfigApplicationContext 进去,源码如下:

public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {/*创建 BeanDefinitionReader 和 BeanDefinitionScanner */this();// 将我们的配置类注册为 BeanDefinitionregister(annotatedClasses);// IoC容器刷新 关键步骤!refresh();
}

3. refresh

以上只有三个方法,其中关键 Spring 源码中的关键代码都在 refresh() 方法之中,点进 refresh() 方法,如下:
refresh() 方法中

	@Overridepublic void refresh() throws BeansException, IllegalStateException {// 同步,线程安全; 防止 fresh还没结束  就又进入改方法 导致容器初始化错乱synchronized (this.startupShutdownMonitor) {// ...invokeBeanFactoryPostProcessors(beanFactory);// ...}// ...}}

4. 执行 postProcessor

在上述的 invokeBeanFactoryPostProcessors(beanFactory) 方法中将 Bean 扫描为 BeanDefinition,注册进 BeanDefinitionMap 中,点进该方法,如下:

	protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());// ...}

5. postProcessor具体执行流程

主要核心流程在上述代码中,点进如下:PostProcessorRegistrationDelegate # invokeBeanFactoryPostProcessors

public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {// Invoke BeanDefinitionRegistryPostProcessors first, if any.Set<String> processedBeans = new HashSet<>();// BeanDefinitionRegistry 是唯一一个定义了 BeanDefinition 注册功能的接口if (beanFactory instanceof BeanDefinitionRegistry) { BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();/*1.执行硬编码注册的后处理器(即我们通过代码加入的 BeanPostProcessor,如果没有指定的话,这个for循环不会执行)*/for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {BeanDefinitionRegistryPostProcessor registryProcessor =(BeanDefinitionRegistryPostProcessor) postProcessor;registryProcessor.postProcessBeanDefinitionRegistry(registry);registryProcessors.add(registryProcessor);}else {regularPostProcessors.add(postProcessor);}}List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();// 2.获取 BeanDefinitionRegistryPostProcessor.class 类型的 bean 的名字 BeanNameString[] postProcessorNames =beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);for (String ppName : postProcessorNames) {/* 2.1先执行优先级是 PriorityOrdered 的 BeanDefinitionRegistryPostProcessor这里执行 ConfigurationClassPostProcessor 处理器,该处理器实现了 PriorityOrdered 接口*/if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));processedBeans.add(ppName);}}sortPostProcessors(currentRegistryProcessors, beanFactory);registryProcessors.addAll(currentRegistryProcessors);// 2.2执行 ConfigurationClassPostProcessorinvokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);currentRegistryProcessors.clear();// 3.和步骤2一样获取 BeanName 一样postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);for (String ppName : postProcessorNames) {// 3.1执行优先级是 Ordered 的 postProcessorif (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));processedBeans.add(ppName);}}sortPostProcessors(currentRegistryProcessors, beanFactory);registryProcessors.addAll(currentRegistryProcessors);invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);currentRegistryProcessors.clear();// Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.boolean reiterate = true;while (reiterate) {reiterate = false;postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);for (String ppName : postProcessorNames) {if (!processedBeans.contains(ppName)) {currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));processedBeans.add(ppName);reiterate = true;}}sortPostProcessors(currentRegistryProcessors, beanFactory);registryProcessors.addAll(currentRegistryProcessors);invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);currentRegistryProcessors.clear();}// Now, invoke the postProcessBeanFactory callback of all processors handled so far.// CGLib代理invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);}else {// Invoke factory processors registered with the context instance.invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);}// BeanFactoryPostProcessor.class类型// Do not initialize FactoryBeans here: We need to leave all regular beans// uninitialized to let the bean factory post-processors apply to them!String[] postProcessorNames =beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);// 筛选出bean工程中存在的所有实现BeanFactoryPostProcessor类的类名称// Separate between BeanFactoryPostProcessors that implement PriorityOrdered,// Ordered, and the rest.List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();List<String> orderedPostProcessorNames = new ArrayList<>();List<String> nonOrderedPostProcessorNames = new ArrayList<>();for (String ppName : postProcessorNames) {if (processedBeans.contains(ppName)) {// skip - already processed in first phase above// 已经存在了,不再处理}else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {// 为PriorityOrdered类型priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));}else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {// 为Ordered类型orderedPostProcessorNames.add(ppName);}else {// 这个就是我们当前需要关心的PostProcessors//nonOrderedPostProcessors添加的不是bean实例,而是BeanDefinitionnonOrderedPostProcessorNames.add(ppName);}}// First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.sortPostProcessors(priorityOrderedPostProcessors, beanFactory);invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);// Next, invoke the BeanFactoryPostProcessors that implement Ordered.List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>();for (String postProcessorName : orderedPostProcessorNames) {orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));}sortPostProcessors(orderedPostProcessors, beanFactory);invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);// Finally, invoke all other BeanFactoryPostProcessors.List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>();for (String postProcessorName : nonOrderedPostProcessorNames) {nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));}invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);// Clear cached merged bean definitions since the post-processors might have// modified the original metadata, e.g. replacing placeholders in values...beanFactory.clearMetadataCache();
}

6. 执行ConfigurationClassPostProcessor

从上边方法的 2.2 处的方法点进去,如下:

private static void invokeBeanDefinitionRegistryPostProcessors(Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry) {for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {postProcessor.postProcessBeanDefinitionRegistry(registry);}
}

上边方法中核心代码只有一行,即执行处理器,点进如下:ConfigurationClassPostProcessor # postProcessBeanDefinitionRegistry

@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {// ...processConfigBeanDefinitions(registry);
}

7. 具体执行ConfigurationClassPostProcessor

点进上述方法:ConfigurationClassPostProcessor # processConfigBeanDefinitions

public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {List<BeanDefinitionHolder> configCandidates = new ArrayList<>();// 1.先去获取当前已经注册的所有的 BeanDefinition// 这里获取的 BeanDefinition 有两类// 一类是Spring自身已经注册的Bean// 另一类是我们自己注册的配置文件,即 Appconfig,这个 BeanDefinition 是在容器刷新 refresh() 方法之前通过 register(annotatedClasses) 注册的String[] candidateNames = registry.getBeanDefinitionNamess();// 2.在这里对已经注册的 BeanDefinition 进行筛选,将我们的配置类 AppConfi 筛选出来加入到 configCandidates 集合中for (String beanName : candidateNames) {BeanDefinition beanDef = registry.getBeanDefinition(beanName);if (ConfigurationClassUtils.isFullConfigurationClass(beanDef) ||ConfigurationClassUtils.isLiteConfigurationClass(beanDef)) {if (logger.isDebugEnabled()) {logger.debug("Bean definition has already been processed as a configuration class: " + beanDef);}}else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));}}// 如果没有 @Configuration 标注的配置类,那么就不需要进行解析了,直接返回if (configCandidates.isEmpty()) {return;}// ... 如果有多个配置类进行排序// 去设置自定义的 BeanNameGenerator,如果我们没设置,那么就获取不到SingletonBeanRegistry sbr = null;if (registry instanceof SingletonBeanRegistry) {sbr = (SingletonBeanRegistry) registry;if (!this.localBeanNameGeneratorSet) {BeanNameGenerator generator = (BeanNameGenerator) sbr.getSingleton(CONFIGURATION_BEAN_NAME_GENERATOR);if (generator != null) {this.componentScanBeanNameGenerator = generator;this.importBeanNameGenerator = generator;}}}if (this.environment == null) {this.environment = new StandardEnvironment();}// 创建一个解析器,用于解析配置类ConfigurationClassParser parser = new ConfigurationClassParser(this.metadataReaderFactory, this.problemReporter, this.environment,this.resourceLoader, this.componentScanBeanNameGenerator, registry);Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size());do {/*3.解析配置类*/parser.parse(candidates);parser.validate();Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());configClasses.removeAll(alreadyParsed);// Read the model and create bean definitions based on its contentif (this.reader == null) {this.reader = new ConfigurationClassBeanDefinitionReader(registry, this.sourceExtractor, this.resourceLoader, this.environment,this.importBeanNameGenerator, parser.getImportRegistry());}this.reader.loadBeanDefinitions(configClasses);alreadyParsed.addAll(configClasses);candidates.clear();if (registry.getBeanDefinitionCount() > candidateNames.length) {String[] newCandidateNames = registry.getBeanDefinitionNames();Set<String> oldCandidateNames = new HashSet<>(Arrays.asList(candidateNames));Set<String> alreadyParsedClasses = new HashSet<>();for (ConfigurationClass configurationClass : alreadyParsed) {alreadyParsedClasses.add(configurationClass.getMetadata().getClassName());}for (String candidateName : newCandidateNames) {if (!oldCandidateNames.contains(candidateName)) {BeanDefinition bd = registry.getBeanDefinition(candidateName);if (ConfigurationClassUtils.checkConfigurationClassCandidate(bd, this.metadataReaderFactory) &&!alreadyParsedClasses.contains(bd.getBeanClassName())) {candidates.add(new BeanDefinitionHolder(bd, candidateName));}}}candidateNames = newCandidateNames;}}while (!candidates.isEmpty());// Register the ImportRegistry as a bean in order to support ImportAware @Configuration classesif (sbr != null && !sbr.containsSingleton(IMPORT_REGISTRY_BEAN_NAME)) {sbr.registerSingleton(IMPORT_REGISTRY_BEAN_NAME, parser.getImportRegistry());}if (this.metadataReaderFactory instanceof CachingMetadataReaderFactory) {// Clear cache in externally provided MetadataReaderFactory; this is a no-op// for a shared cache since it'll be cleared by the ApplicationContext.((CachingMetadataReaderFactory) this.metadataReaderFactory).clearCache();}
}

8. 对配置类进行解析

上述步骤3的解析方法,点进去,如下: ConfigurationClassParser # parse

public void parse(Set<BeanDefinitionHolder> configCandidates) {// configCandidates 即为传进来的配置类for (BeanDefinitionHolder holder : configCandidates) {BeanDefinition bd = holder.getBeanDefinition();try {// 表示是注解类型的 BeanDefinition,我们在本次示例使用的就是注解类型的,因此会进入这里第一个 parse 方法if (bd instanceof AnnotatedBeanDefinition) {parse(((AnnotatedBeanDefinition) bd).getMetadata(), holder.getBeanName());}else if (bd instanceof AbstractBeanDefinition && ((AbstractBeanDefinition) bd).hasBeanClass()) {parse(((AbstractBeanDefinition) bd).getBeanClass(), holder.getBeanName());}else {parse(bd.getBeanClassName(), holder.getBeanName());}}catch (BeanDefinitionStoreException ex) {throw ex;}catch (Throwable ex) {throw new BeanDefinitionStoreException("Failed to parse configuration class [" + bd.getBeanClassName() + "]", ex);}}this.deferredImportSelectorHandler.process();
}

点进上边第一个 parse 方法,如下: ConfigurationClassParser # parse

protected final void parse(AnnotationMetadata metadata, String beanName) throws IOException {processConfigurationClass(new ConfigurationClass(metadata, beanName));
}

点进上边方法,如下:ConfigurationClassParser # processConfigurationClass

protected void processConfigurationClass(ConfigurationClass configClass) throws IOException {// ...// 将配置类包装成为 SourceClass ,方便统一解析SourceClass sourceClass = asSourceClass(configClass);do {/解析配置类*/sourceClass = doProcessConfigurationClass(configClass, sourceClass);}while (sourceClass != null);this.configurationClasses.put(configClass, configClass);}

9. 处理配置类上的注解

点进上边解析配置类的方法,如下: ConfigurationClassParser # doProcessConfigurationClass

@Nullable
protected final SourceClass doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass)throws IOException {if (configClass.getMetadata().isAnnotated(Component.class.getName())) {// 如果配置类还有嵌套的内部类,先进行处理processMemberClasses(configClass, sourceClass);}// 1.处理 @PropertySource 注解for (AnnotationAttributes propertySource : AnnotationConfigUtils.attributesForRepeatable(sourceClass.getMetadata(), PropertySources.class,org.springframework.context.annotation.PropertySource.class)) {if (this.environment instanceof ConfigurableEnvironment) {processPropertySource(propertySource);}else {logger.info("Ignoring @PropertySource annotation on [" + sourceClass.getMetadata().getClassName() +"]. Reason: Environment must implement ConfigurableEnvironment");}}// 2.处理 @ComponentScan 注解Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable(sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class);if (!componentScans.isEmpty() &&!this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) {for (AnnotationAttributes componentScan : componentScans) {/2.1 通过扫描器去扫描 @ComponentScan 标注路径下的类/Set<BeanDefinitionHolder> scannedBeanDefinitions =this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());// ... 进行一些其他的小处理}}// Process any @Import annotationsprocessImports(configClass, sourceClass, getImports(sourceClass), true);// Process any @ImportResource annotationsAnnotationAttributes importResource =AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class);if (importResource != null) {String[] resources = importResource.getStringArray("locations");Class<? extends BeanDefinitionReader> readerClass = importResource.getClass("reader");for (String resource : resources) {String resolvedResource = this.environment.resolveRequiredPlaceholders(resource);configClass.addImportedResource(resolvedResource, readerClass);}}// Process individual @Bean methodsSet<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass);for (MethodMetadata methodMetadata : beanMethods) {configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));}// Process default methods on interfacesprocessInterfaces(configClass, sourceClass);// Process superclass, if anyif (sourceClass.getMetadata().hasSuperClass()) {String superclass = sourceClass.getMetadata().getSuperClassName();if (superclass != null && !superclass.startsWith("java") &&!this.knownSuperclasses.containsKey(superclass)) {this.knownSuperclasses.put(superclass, configClass);// Superclass found, return its annotation metadata and recursereturn sourceClass.getSuperClass();}}// No superclass -> processing is completereturn null;
}

10. 处理配置类的@Component

2.1 上述代码分支: ComponentScanAnnotationParser # parse

public Set<BeanDefinitionHolder> parse(AnnotationAttributes componentScan, final String declaringClass) {ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(this.registry,componentScan.getBoolean("useDefaultFilters"), this.environment, this.resourceLoader);// ... 设置scanner的一些属性,包括 includeFilters 和 excludeFilters// 拿到扫描路径Set<String> basePackages = new LinkedHashSet<>();String[] basePackagesArray = componentScan.getStringArray("basePackages");for (String pkg : basePackagesArray) {String[] tokenized = StringUtils.tokenizeToStringArray(this.environment.resolvePlaceholders(pkg),ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);Collections.addAll(basePackages, tokenized);}for (Class<?> clazz : componentScan.getClassArray("basePackageClasses")) {basePackages.add(ClassUtils.getPackageName(clazz));}if (basePackages.isEmpty()) {basePackages.add(ClassUtils.getPackageName(declaringClass));}scanner.addExcludeFilter(new AbstractTypeHierarchyTraversingFilter(false, false) {@Overrideprotected boolean matchClassName(String className) {return declaringClass.equals(className);}});/*核心代码,进行扫描*/return scanner.doScan(StringUtils.toStringArray(basePackages));
}

11. 扫描basePackage

点进 scanner.doScan,如下:ClassPathBeanDefinitionScanner # 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) {// 1.对 basePackage 扫描得到 BeanDefinition 的集合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) {// 2.将 BeanDefinition 设置成默认的 BeanDefinitionpostProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);}if (candidate instanceof AnnotatedBeanDefinition) {// 3.处理 BeanDefinition 的通用注解,包括 @Lazy、@Primary、@DependsOn、@Role、@Description 注解AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);}// 4. 判断当前 beanDefinition 是否与其他 BeanDefinition 存在冲突,如果不冲突,返回trueif (checkCandidate(beanName, candidate)) {BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);definitionHolder =AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);beanDefinitions.add(definitionHolder);// 5.注册 BeanDefinitionregisterBeanDefinition(definitionHolder, this.registry);}}}return beanDefinitions;
}

12. 扫描得到BeanDefinition集合

对上述代码 1. 步骤,即扫描 basePackage 的方法,点进去,如下:ClassPathScanningCandidateComponentProvider # findCandidateComponents

public Set<BeanDefinition> findCandidateComponents(String basePackage) {if (this.componentsIndex != null && indexSupportsIncludeFilters()) {return addCandidateComponentsFromIndex(this.componentsIndex, basePackage);}else {// 核心代码return scanCandidateComponents(basePackage);}
}

点进上述方法,如下:ClassPathScanningCandidateComponentProvider # scanCandidateComponents

private Set<BeanDefinition> scanCandidateComponents(String basePackage) {Set<BeanDefinition> candidates = new LinkedHashSet<>();try {// 1.先去拿到 class 文件所在路径,即:classpath*:com/analysis/service//*.classString packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +resolveBasePackage(basePackage) + '/' + this.resourcePattern;// 2.将 class 文件封装为 Resource 对象,这个 Resource 就是用来封装底层资源的,Resource 继承了 InputStreamSourceResource[] resources = getResourcePatternResolver().getResources(packageSearchPath);boolean traceEnabled = logger.isTraceEnabled();boolean debugEnabled = logger.isDebugEnabled();for (Resource resource : resources) {if (traceEnabled) {logger.trace("Scanning " + resource);}if (resource.isReadable()) {try {/3.通过MetadataReaderFactory解析Resource对象得到MetadataReader这里返回的 MetaDataReader 其实就是 SimpleMetadataReader,该类就是用于解析 class 文件之后,提供对 class 文件访问的接口getMetadataReaderFactory() 获取的就是 CachingMetadataReaderFactory 对象,将 resource(也就是class文件) 解析成 MetadataReader 之后,将 <resource, MetadataReader> 的 K,V 键值对缓存在 CachingMetadataReaderFactory 对象中(MetadataReaderFactory具体的实现类为:CachingMetadataReaderFactoryMetadataReader的具体实现类为:SimpleMetadataReader)*/MetadataReader metadataReader = getMetadataReaderFactory().getMetadataReader(resource);/4.通过 include 、 exclude 、 @Conditional 三个条件进行过滤*/if (isCandidateComponent(metadataReader)) {// 5.先生成该 Bean 的 ScannedGenericBeanDefinition 对象ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader);sbd.setResource(resource);sbd.setSource(resource);// 6.再判断是不是对应的类是不是接口或抽象类if (isCandidateComponent(sbd)) {if (debugEnabled) {logger.debug("Identified candidate component class: " + resource);}// 7.如果筛选通过,那么就表示扫描到了一个 Bean,将 ScannedGenericBeanDefinition 加入结果集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 (Throwable ex) {throw new BeanDefinitionStoreException("Failed to read candidate component class: " + resource, ex);}}else {if (traceEnabled) {logger.trace("Ignored because not readable: " + resource);}}}}catch (IOException ex) {throw new BeanDefinitionStoreException("I/O failure during classpath scanning", ex);}return candidates;
}

13.注册BeanDefinition

在上述代码中,我们拿到了 basePackage 下的所有的符合条件的类,接下来要继续回到 11. 扫描basePackage(ctrl+左键跳转) 中,对扫描到的 BeanDefinition 集合进行处理,处理之后,要对得到的 BeanDefinition 进行注册,即进入到 11. 扫描basePackage 的步骤5的代码中,如下:ClassPathBeanDefinitionScanner # registerBeanDefinition

protected void registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry) {BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, registry);
}

点进,如下:BeanDefinitionReaderUtils # registerBeanDefinition

public static void registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)throws BeanDefinitionStoreException {String beanName = definitionHolder.getBeanName();// 1.通过beanName ,注册BeanDefinitionregistry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());// Register aliases for bean name, if any.// 如果有别名,则通过别名注册String[] aliases = definitionHolder.getAliases();if (aliases != null) {for (String alias : aliases) {registry.registerAlias(beanName, alias);}}
}

14. 根据beanName注册BeanDefinition

点进上边代码步骤1,如下:DefaultListableBeanFactory # registerBeanDefinition

@Override
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)throws BeanDefinitionStoreException {Assert.hasText(beanName, "Bean name must not be empty");Assert.notNull(beanDefinition, "BeanDefinition must not be null");// 校验 BeanDefinitionif (beanDefinition instanceof AbstractBeanDefinition) {try {((AbstractBeanDefinition) beanDefinition).validate();}catch (BeanDefinitionValidationException ex) {throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,"Validation of bean definition failed", ex);}}// 首先从 beanDefinitionMap 查看是否已经存在 BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);if (existingDefinition != null) {// 如果已经存在且不允许覆盖,抛出异常if (!isAllowBeanDefinitionOverriding()) {throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);}else if (existingDefinition.getRole() < beanDefinition.getRole()) {// 0 ROLE_APPLICATION表示这个 Bean 是用户自己定义的 Bean;// 1 ROLE_SUPPORT 表示这个 Bean 是某些复杂配置的支撑部分;// 2 ROLE_INFRASTRUCTURE 表示这是一个 Spring 内部的 Bean// e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTUREif (logger.isInfoEnabled()) {logger.info("Overriding user-defined bean definition for bean '" + beanName +"' with a framework-generated bean definition: replacing [" +existingDefinition + "] with [" + beanDefinition + "]");}}else if (!beanDefinition.equals(existingDefinition)) {if (logger.isDebugEnabled()) {logger.debug("Overriding bean definition for bean '" + beanName +"' with a different definition: replacing [" + existingDefinition +"] with [" + beanDefinition + "]");}}else {if (logger.isTraceEnabled()) {logger.trace("Overriding bean definition for bean '" + beanName +"' with an equivalent definition: replacing [" + existingDefinition +"] with [" + beanDefinition + "]");}}// 将解析的 BeanDefinition 放入 Mapthis.beanDefinitionMap.put(beanName, beanDefinition);}else { // 如果 Map 中不存在已经解析好的 BeanDefinition// 工厂的 Bean 的创建是否已经开始if (hasBeanCreationStarted()) {// 加锁,控制并发synchronized (this.beanDefinitionMap) {//将一个一个的beanDefinition放入到一个Map中(即为IoC容器)this.beanDefinitionMap.put(beanName, beanDefinition);List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1);updatedDefinitions.addAll(this.beanDefinitionNames);updatedDefinitions.add(beanName);this.beanDefinitionNames = updatedDefinitions;removeManualSingletonName(beanName);}}else {// Still in startup registration phase// 仍在启动注册阶段  添加key-value形式的bean定义信息this.beanDefinitionMap.put(beanName, beanDefinition);this.beanDefinitionNames.add(beanName);removeManualSingletonName(beanName);}this.frozenBeanDefinitionNames = null;}// 如果已经存在 或者 包含beanNameif (existingDefinition != null || containsSingleton(beanName)) {// 重置所有beanName对应的缓存resetBeanDefinition(beanName);}
}

15. 完成注册

至此,BeanDefinition的注册就完成了,也就是完成了9. 处理配置类上的注解的步骤2.1的代码