网站建设的市场定位,网页设计优秀作品展示,个人网站做公司网站,漯河做网站文章目录一、源码时序图二、源码解析1. 运行案例程序启动类2. 解析AnnotationConfigApplicationContext类的AnnotationConfigApplicationContext(Class?... componentClasses)构造方法3. 解析AbstractApplicationContext类的refresh()方法4. 解析AbstractApplicationC…
文章目录一、源码时序图二、源码解析1. 运行案例程序启动类2. 解析AnnotationConfigApplicationContext类的AnnotationConfigApplicationContext(Class?... componentClasses)构造方法3. 解析AbstractApplicationContext类的refresh()方法4. 解析AbstractApplicationContext类的invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory)方法5. 解析PostProcessorRegistrationDelegate类的invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, ListbeanFactoryPostProcessors)方法6. 解析PostProcessorRegistrationDelegate类的invokeBeanDefinitionRegistryPostProcessors(Collection? extends BeanDefinitionRegistryPostProcessor postProcessors, BeanDefinitionRegistry registry, ApplicationStartup applicationStartup)方法7. 解析ConfigurationClassPostProcessor类的postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry)方法8. 解析ConfigurationClassPostProcessor类的processConfigBeanDefinitions(BeanDefinitionRegistry registry)方法9. 解析ConfigurationClassParser类的parse(SetconfigCandidates)方法10. 解析ConfigurationClassParser类的parse(AnnotationMetadata metadata, String beanName)方法11. 解析ConfigurationClassParser类的processConfigurationClass(ConfigurationClass configClass, Predicatefilter)方法12. 解析ConfigurationClassParser类的doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass, Predicatefilter)方法13. 解析ConfigurationClassParser类的retrieveBeanMethodMetadata(SourceClass sourceClass)方法14. 回到ConfigurationClassParser类的doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass, Predicatefilter)方法。15. 回到ConfigurationClassPostProcessor类的processConfigBeanDefinitions(BeanDefinitionRegistry registry)方法16. 解析ConfigurationClassBeanDefinitionReader类的loadBeanDefinitions(SetconfigurationModel)方法17. 解析ConfigurationClassBeanDefinitionReader类的loadBeanDefinitionsForConfigurationClass(ConfigurationClass configClass, TrackedConditionEvaluator trackedConditionEvaluator)方法18. 解析ConfigurationClassBeanDefinitionReader类的loadBeanDefinitionsForBeanMethod(BeanMethod beanMethod)方法19. 解析DefaultListableBeanFactory类的registerBeanDefinition(String beanName, BeanDefinition beanDefinition)方法一、源码时序图 本节就以源码时序图的方式直观的感受下Bean注解在Spring源码层面的执行流程。Bean注解在Spring源码层面的执行流程如图所示 由图可以看出Bean注解在Spring源码层面的执行流程会涉及到BeanTest类、AnnotationConfigApplicationContext类、AbstractApplicationContext类、PostProcessorRegistrationDelegate类、ConfigurationClassPostProcessor类、ConfigurationClassParser类、ConfigurationClassBeanDefinitionReader类和DefaultListableBeanFactory类。具体的源码执行细节参见源码解析部分。 二、源码解析 Bean注解在Spring源码层面的执行流程结合源码执行的时序图会理解的更加深刻。 1. 运行案例程序启动类 在BeanTest类的main()方法中调用了AnnotationConfigApplicationContext类的构造方法并传入了ComponentScanConfig类的Class对象来创建IOC容器。接下来会进入AnnotationConfigApplicationContext类的构造方法。 2. 解析AnnotationConfigApplicationContext类的AnnotationConfigApplicationContext(Class?… componentClasses)构造方法
public AnnotationConfigApplicationContext(Class?... componentClasses) {this();register(componentClasses);refresh();
}可以看到在上述构造方法中调用了refresh()方法来刷新IOC容器。 3. 解析AbstractApplicationContext类的refresh()方法
Override
public void refresh() throws BeansException, IllegalStateException {synchronized (this.startupShutdownMonitor) {//############省略其他代码##############try {//############省略其他代码##############invokeBeanFactoryPostProcessors(beanFactory);//############省略其他代码##############}catch (BeansException ex) {//############省略其他代码##############}finally {//############省略其他代码##############}}
}refresh()方法是Spring中一个非常重要的方法很多重要的功能和特性都是通过refresh()方法进行注入的。可以看到在refresh()方法中调用了invokeBeanFactoryPostProcessors()方法。 4. 解析AbstractApplicationContext类的invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory)方法
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());if (!NativeDetector.inNativeImage() beanFactory.getTempClassLoader() null beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));}
}可以看到在AbstractApplicationContext类的invokeBeanFactoryPostProcessors()方法中调用了PostProcessorRegistrationDelegate类的invokeBeanFactoryPostProcessors()方法。 5. 解析PostProcessorRegistrationDelegate类的invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, ListbeanFactoryPostProcessors)方法 由于方法的源码比较长这里只关注当前最核心的逻辑如下所示 public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, ListBeanFactoryPostProcessor beanFactoryPostProcessors) {//############省略其他代码##############ListBeanDefinitionRegistryPostProcessor currentRegistryProcessors new ArrayList();// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.String[] postProcessorNames beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);for (String ppName : postProcessorNames) {if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));processedBeans.add(ppName);}}sortPostProcessors(currentRegistryProcessors, beanFactory);registryProcessors.addAll(currentRegistryProcessors);invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());currentRegistryProcessors.clear();// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.postProcessorNames beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);for (String ppName : postProcessorNames) {if (!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, beanFactory.getApplicationStartup());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, beanFactory.getApplicationStartup());currentRegistryProcessors.clear();}//############省略其他代码##############
}可以看到在PostProcessorRegistrationDelegate类的invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, ListbeanFactoryPostProcessors)方法中BeanDefinitionRegistryPostProcessor的实现类在执行逻辑上会有先后顺序并且最终都会调用invokeBeanDefinitionRegistryPostProcessors()方法。 6. 解析PostProcessorRegistrationDelegate类的invokeBeanDefinitionRegistryPostProcessors(Collection? extends BeanDefinitionRegistryPostProcessor postProcessors, BeanDefinitionRegistry registry, ApplicationStartup applicationStartup)方法
private static void invokeBeanDefinitionRegistryPostProcessors(Collection? extends BeanDefinitionRegistryPostProcessor postProcessors, BeanDefinitionRegistry registry, ApplicationStartup applicationStartup) {for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {StartupStep postProcessBeanDefRegistry applicationStartup.start(spring.context.beandef-registry.post-process).tag(postProcessor, postProcessor::toString);postProcessor.postProcessBeanDefinitionRegistry(registry);postProcessBeanDefRegistry.end();}
}可以看到在invokeBeanDefinitionRegistryPostProcessors()方法中会循环遍历postProcessors集合中的每个元素调用postProcessBeanDefinitionRegistry()方法注册Bean的定义信息。 7. 解析ConfigurationClassPostProcessor类的postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry)方法
Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {//##########省略其他代码###################processConfigBeanDefinitions(registry);
}可以看到在postProcessBeanDefinitionRegistry()方法中会调用processConfigBeanDefinitions()方法。 8. 解析ConfigurationClassPostProcessor类的processConfigBeanDefinitions(BeanDefinitionRegistry registry)方法 这里重点关注方法中的如下逻辑 public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {//############省略其他代码#################// Parse each Configuration classConfigurationClassParser parser new ConfigurationClassParser(this.metadataReaderFactory, this.problemReporter, this.environment,this.resourceLoader, this.componentScanBeanNameGenerator, registry);SetBeanDefinitionHolder candidates new LinkedHashSet(configCandidates);SetConfigurationClass alreadyParsed new HashSet(configCandidates.size());do {StartupStep processConfig this.applicationStartup.start(spring.context.config-classes.parse);parser.parse(candidates);parser.validate();//############省略其他代码#################this.reader.loadBeanDefinitions(configClasses);alreadyParsed.addAll(configClasses);processConfig.tag(classCount, () - String.valueOf(configClasses.size())).end();//############省略其他代码#################}while (!candidates.isEmpty());//############省略其他代码#################
}可以看到在processConfigBeanDefinitions()方法中创建了一个ConfigurationClassParser类型的对象parser并且调用了parser的parse()方法来解析类的配置信息。 9. 解析ConfigurationClassParser类的parse(SetconfigCandidates)方法
public void parse(SetBeanDefinitionHolder configCandidates) {for (BeanDefinitionHolder holder : configCandidates) {BeanDefinition bd holder.getBeanDefinition();try {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();
}可以看到在ConfigurationClassParser类的parse(SetconfigCandidates)方法中调用了类中的另一个parse()方法。 10. 解析ConfigurationClassParser类的parse(AnnotationMetadata metadata, String beanName)方法
protected final void parse(AnnotationMetadata metadata, String beanName) throws IOException {processConfigurationClass(new ConfigurationClass(metadata, beanName), DEFAULT_EXCLUSION_FILTER);
}可以看到上述parse()方法的实现比较简单直接调用了processConfigurationClass()方法。 11. 解析ConfigurationClassParser类的processConfigurationClass(ConfigurationClass configClass, Predicatefilter)方法
protected void processConfigurationClass(ConfigurationClass configClass, PredicateString filter) throws IOException {//###############省略其他代码####################SourceClass sourceClass asSourceClass(configClass, filter);do {sourceClass doProcessConfigurationClass(configClass, sourceClass, filter);}while (sourceClass ! null);this.configurationClasses.put(configClass, configClass);
}可以看到在processConfigurationClass()方法中会通过do-while()循环获取配置类和其父类的注解信息SourceClass类中会封装配置类上注解的详细信息。在在processConfigurationClass()方法中调用了doProcessConfigurationClass()方法。 12. 解析ConfigurationClassParser类的doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass, Predicatefilter)方法
protected final SourceClass doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass, PredicateString filter)throws IOException {//##################省略其他代码##################// Process individual Bean methodsSetMethodMetadata beanMethods retrieveBeanMethodMetadata(sourceClass);for (MethodMetadata methodMetadata : beanMethods) {configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));}//##################省略其他代码##################// No superclass - processing is completereturn null;
}这里只关注与Bean注解相关的方法可以看到在doProcessConfigurationClass()方法中调用了retrieveBeanMethodMetadata()方法来解析sourceClass中有关Bean注解的属性信息。 13. 解析ConfigurationClassParser类的retrieveBeanMethodMetadata(SourceClass sourceClass)方法
private SetMethodMetadata retrieveBeanMethodMetadata(SourceClass sourceClass) {AnnotationMetadata original sourceClass.getMetadata();SetMethodMetadata beanMethods original.getAnnotatedMethods(Bean.class.getName());if (beanMethods.size() 1 original instanceof StandardAnnotationMetadata) {try {AnnotationMetadata asm this.metadataReaderFactory.getMetadataReader(original.getClassName()).getAnnotationMetadata();SetMethodMetadata asmMethods asm.getAnnotatedMethods(Bean.class.getName());if (asmMethods.size() beanMethods.size()) {SetMethodMetadata selectedMethods new LinkedHashSet(asmMethods.size());for (MethodMetadata asmMethod : asmMethods) {for (MethodMetadata beanMethod : beanMethods) {if (beanMethod.getMethodName().equals(asmMethod.getMethodName())) {selectedMethods.add(beanMethod);break;}}}if (selectedMethods.size() beanMethods.size()) {beanMethods selectedMethods;}}}catch (IOException ex) {logger.debug(Failed to read class file via ASM for determining Bean method order, ex);}}return beanMethods;
}可以看到在retrieveBeanMethodMetadata()方法中主要是解析Bean注解并且将解析到的方法元数据存入 Set集合中并返回。 14. 回到ConfigurationClassParser类的doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass, Predicatefilter)方法。 这里还是重点看下方法中与Bean注解有关的代码片段如下所示 SetMethodMetadata beanMethods retrieveBeanMethodMetadata(sourceClass);
for (MethodMetadata methodMetadata : beanMethods) {configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
}调用retrieveBeanMethodMetadata()方法获取到标注了Bean注解的方法的元数据集合后遍历方法的元数据集合将方法的元数据methodMetadata和配置类configClass传入BeanMethod类的构造方法创建BeanMethod对象并调用configClass的addBeanMethod()方法传入创建的BeanMethod对象。 configClass的addBeanMethod()方法的源码详见org.springframework.context.annotation.ConfigurationClass#addBeanMethod(BeanMethod method)如下所示 void addBeanMethod(BeanMethod method) {this.beanMethods.add(method);
}可以看到在addBeanMethod()方法中调用了beanMethods的add()方法添加BeanMethod对象。 beanMethods的源码详见org.springframework.context.annotation.ConfigurationClass#beanMethods如下所示 private final SetBeanMethod beanMethods new LinkedHashSet();可以看到beanMethods是一个LinkedHashSet类型的集合。也就是说在ConfigurationClassParser类的doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass, Predicatefilter)方法中会将解析出的标注了Bean注解的元数据封装成BeanMethod对象添加到一个LinkedHashSet类型的beanMethods集合中。 15. 回到ConfigurationClassPostProcessor类的processConfigBeanDefinitions(BeanDefinitionRegistry registry)方法 此时重点关注下如下源码片段 public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {//############省略其他代码#################do {//############省略其他代码#################this.reader.loadBeanDefinitions(configClasses);alreadyParsed.addAll(configClasses);processConfig.tag(classCount, () - String.valueOf(configClasses.size())).end();//############省略其他代码#################}while (!candidates.isEmpty());//############省略其他代码#################
}可以看到在processConfigBeanDefinitions()方法的do-while()循环中调用了reader的loadBeanDefinitions()方法来加载Bean的定义信息。 16. 解析ConfigurationClassBeanDefinitionReader类的loadBeanDefinitions(SetconfigurationModel)方法
public void loadBeanDefinitions(SetConfigurationClass configurationModel) {TrackedConditionEvaluator trackedConditionEvaluator new TrackedConditionEvaluator();for (ConfigurationClass configClass : configurationModel) {loadBeanDefinitionsForConfigurationClass(configClass, trackedConditionEvaluator);}
}可以看到在loadBeanDefinitions()方法中会循环遍历传入的configurationModel集合并调用loadBeanDefinitionsForConfigurationClass()方法处理遍历的每个元素。 17. 解析ConfigurationClassBeanDefinitionReader类的loadBeanDefinitionsForConfigurationClass(ConfigurationClass configClass, TrackedConditionEvaluator trackedConditionEvaluator)方法
private void loadBeanDefinitionsForConfigurationClass(ConfigurationClass configClass, TrackedConditionEvaluator trackedConditionEvaluator) {//###############省略其他代码################for (BeanMethod beanMethod : configClass.getBeanMethods()) {loadBeanDefinitionsForBeanMethod(beanMethod);}//###############省略其他代码################
}可以看到在loadBeanDefinitionsForConfigurationClass()方法中会循环遍历通过configClass获取到的BeanMethod集合并调用loadBeanDefinitionsForBeanMethod()方法处理遍历的每个BeanMethod对象。 18. 解析ConfigurationClassBeanDefinitionReader类的loadBeanDefinitionsForBeanMethod(BeanMethod beanMethod)方法
private void loadBeanDefinitionsForBeanMethod(BeanMethod beanMethod) {ConfigurationClass configClass beanMethod.getConfigurationClass();MethodMetadata metadata beanMethod.getMetadata();String methodName metadata.getMethodName();if (this.conditionEvaluator.shouldSkip(metadata, ConfigurationPhase.REGISTER_BEAN)) {configClass.skippedBeanMethods.add(methodName);return;}if (configClass.skippedBeanMethods.contains(methodName)) {return;}AnnotationAttributes bean AnnotationConfigUtils.attributesFor(metadata, Bean.class);Assert.state(bean ! null, No Bean annotation attributes);ListString names new ArrayList(Arrays.asList(bean.getStringArray(name)));String beanName (!names.isEmpty() ? names.remove(0) : methodName);for (String alias : names) {this.registry.registerAlias(beanName, alias);}if (isOverriddenByExistingDefinition(beanMethod, beanName)) {if (beanName.equals(beanMethod.getConfigurationClass().getBeanName())) {throw new BeanDefinitionStoreException(beanMethod.getConfigurationClass().getResource().getDescription(),beanName, Bean name derived from Bean method beanMethod.getMetadata().getMethodName() clashes with bean name for containing configuration class; please make those names unique!);}return;}ConfigurationClassBeanDefinition beanDef new ConfigurationClassBeanDefinition(configClass, metadata, beanName);beanDef.setSource(this.sourceExtractor.extractSource(metadata, configClass.getResource()));if (metadata.isStatic()) {// static Bean methodif (configClass.getMetadata() instanceof StandardAnnotationMetadata sam) {beanDef.setBeanClass(sam.getIntrospectedClass());}else {beanDef.setBeanClassName(configClass.getMetadata().getClassName());}beanDef.setUniqueFactoryMethodName(methodName);}else {// instance Bean methodbeanDef.setFactoryBeanName(configClass.getBeanName());beanDef.setUniqueFactoryMethodName(methodName);}if (metadata instanceof StandardMethodMetadata sam) {beanDef.setResolvedFactoryMethod(sam.getIntrospectedMethod());}beanDef.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_CONSTRUCTOR);AnnotationConfigUtils.processCommonDefinitionAnnotations(beanDef, metadata);boolean autowireCandidate bean.getBoolean(autowireCandidate);if (!autowireCandidate) {beanDef.setAutowireCandidate(false);}String initMethodName bean.getString(initMethod);if (StringUtils.hasText(initMethodName)) {beanDef.setInitMethodName(initMethodName);}String destroyMethodName bean.getString(destroyMethod);beanDef.setDestroyMethodName(destroyMethodName);ScopedProxyMode proxyMode ScopedProxyMode.NO;AnnotationAttributes attributes AnnotationConfigUtils.attributesFor(metadata, Scope.class);if (attributes ! null) {beanDef.setScope(attributes.getString(value));proxyMode attributes.getEnum(proxyMode);if (proxyMode ScopedProxyMode.DEFAULT) {proxyMode ScopedProxyMode.NO;}}BeanDefinition beanDefToRegister beanDef;if (proxyMode ! ScopedProxyMode.NO) {BeanDefinitionHolder proxyDef ScopedProxyCreator.createScopedProxy(new BeanDefinitionHolder(beanDef, beanName), this.registry,proxyMode ScopedProxyMode.TARGET_CLASS);beanDefToRegister new ConfigurationClassBeanDefinition((RootBeanDefinition) proxyDef.getBeanDefinition(), configClass, metadata, beanName);}if (logger.isTraceEnabled()) {logger.trace(String.format(Registering bean definition for Bean method %s.%s(),configClass.getMetadata().getClassName(), beanName));}this.registry.registerBeanDefinition(beanName, beanDefToRegister);
}可以看到在loadBeanDefinitionsForBeanMethod()方法中解析了Bean注解中的属性信息并将解析出的信息封装到一个BeanDefinition对象中最终会调用registry对象的registerBeanDefinition()方法将封装的BeanDefinition对象注册到IOC容器中。 19. 解析DefaultListableBeanFactory类的registerBeanDefinition(String beanName, BeanDefinition beanDefinition)方法
Override
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)throws BeanDefinitionStoreException {//##############省略其他代码#################BeanDefinition existingDefinition this.beanDefinitionMap.get(beanName);if (existingDefinition ! null) {//##############省略其他代码#################this.beanDefinitionMap.put(beanName, beanDefinition);}else {//##############省略其他代码#################if (hasBeanCreationStarted()) {// Cannot modify startup-time collection elements anymore (for stable iteration)synchronized (this.beanDefinitionMap) {this.beanDefinitionMap.put(beanName, beanDefinition);ListString updatedDefinitions new ArrayList(this.beanDefinitionNames.size() 1);updatedDefinitions.addAll(this.beanDefinitionNames);updatedDefinitions.add(beanName);this.beanDefinitionNames updatedDefinitions;removeManualSingletonName(beanName);}}else {// Still in startup registration phasethis.beanDefinitionMap.put(beanName, beanDefinition);this.beanDefinitionNames.add(beanName);removeManualSingletonName(beanName);}this.frozenBeanDefinitionNames null;}if (existingDefinition ! null || containsSingleton(beanName)) {resetBeanDefinition(beanName);}else if (isConfigurationFrozen()) {clearByTypeCache();}
}可以看到Spring会解析这些标注了Bean注解的方法将解析出的信息封装成BeanDefinition对象注册到beanDefinitionMap中。这一点和第1章中注册ConfigurationClassPostProcessor类的Bean定义信息有点类似。 好了至此Bean注解在Spring源码中的执行流程分析完毕。