日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

spring boot实战(第十篇)Spring boot Bean加载源码分析

發布時間:2025/3/21 javascript 15 豆豆
生活随笔 收集整理的這篇文章主要介紹了 spring boot实战(第十篇)Spring boot Bean加载源码分析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言

前面的文章描述了Application對應Bean的創建,本篇將闡述spring boot中bean的創建過程

?

refresh

?

首先來看SpringApplication#run方法中refresh()方法

[html]?view plain?copy

  • //?Refresh?the?context??
  • ????????????refresh(context);??

  • 調用的是AbstractApplicationContext中的refresh方法

    [html]?view plain?copy

  • protected?void?refresh(ApplicationContext?applicationContext)?{??
  • ????????Assert.isInstanceOf(AbstractApplicationContext.class,?applicationContext);??
  • ????????((AbstractApplicationContext)?applicationContext).refresh();??
  • ????}??
  • 方法定義如下:

    [html]?view plain?copy

  • public?void?refresh()?throws?BeansException,?IllegalStateException?{??
  • ????????synchronized?(this.startupShutdownMonitor)?{??
  • ????????????//?Prepare?this?context?for?refreshing.??
  • ????????????prepareRefresh();??
  • ??
  • ????????????//?Tell?the?subclass?to?refresh?the?internal?bean?factory.??
  • ????????????ConfigurableListableBeanFactory?beanFactory?=?obtainFreshBeanFactory();??
  • ??
  • ????????????//?Prepare?the?bean?factory?for?use?in?this?context.??
  • ????????????prepareBeanFactory(beanFactory);??
  • ??
  • ????????????try?{??
  • ????????????????//?Allows?post-processing?of?the?bean?factory?in?context?subclasses.??
  • ????????????????postProcessBeanFactory(beanFactory);??
  • ??
  • ????????????????//?Invoke?factory?processors?registered?as?beans?in?the?context.??
  • ????????????????invokeBeanFactoryPostProcessors(beanFactory);??
  • ??
  • ????????????????//?Register?bean?processors?that?intercept?bean?creation.??
  • ????????????????registerBeanPostProcessors(beanFactory);??
  • ??
  • ????????????????//?Initialize?message?source?for?this?context.??
  • ????????????????initMessageSource();??
  • ??
  • ????????????????//?Initialize?event?multicaster?for?this?context.??
  • ????????????????initApplicationEventMulticaster();??
  • ??
  • ????????????????//?Initialize?other?special?beans?in?specific?context?subclasses.??
  • ????????????????onRefresh();??
  • ??
  • ????????????????//?Check?for?listener?beans?and?register?them.??
  • ????????????????registerListeners();??
  • ??
  • ????????????????//?Instantiate?all?remaining?(non-lazy-init)?singletons.??
  • ????????????????finishBeanFactoryInitialization(beanFactory);??
  • ??
  • ????????????????//?Last?step:?publish?corresponding?event.??
  • ????????????????finishRefresh();??
  • ????????????}??
  • ??
  • ????????????catch?(BeansException?ex)?{??
  • ????????????????logger.warn("Exception?encountered?during?context?initialization?-?cancelling?refresh?attempt",?ex);??
  • ??
  • ????????????????//?Destroy?already?created?singletons?to?avoid?dangling?resources.??
  • ????????????????destroyBeans();??
  • ??
  • ????????????????//?Reset?'active'?flag.??
  • ????????????????cancelRefresh(ex);??
  • ??
  • ????????????????//?Propagate?exception?to?caller.??
  • ????????????????throw?ex;??
  • ????????????}??
  • ????????}??
  • ????}??

  • 該方法中涉及的過程非常多,需要一步步來分析

    ?

    獲取BeanFactory

    [html]?view plain?copy

  • ConfigurableListableBeanFactory?beanFactory?=?obtainFreshBeanFactory();??
  • 通過前面的文章應該知道對應的BeanFactory為DefaultListableBeanFactory

    ?

    直奔主題來看如下方法

    [html]?view plain?copy

  • invokeBeanFactoryPostProcessors(beanFactory);??
  • ?

    [html]?view plain?copy

  • protected?void?invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory?beanFactory)?{??
  • ????????PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory,?getBeanFactoryPostProcessors());??
  • ????}??
  • 首先來看getBeanFactoryPostProcessors(),其對應值為:ConfigurationWarningsApplicationContextInitializer$ConfigurationWarningsPostProcessor、PropertySourceOrderingPostProcessor

    ?

    ConfigurationWarningsApplicationContextInitializer是在ConfigurationWarningsApplicationContextInitializer中執行

    [html]?view plain?copy

  • public?void?initialize(ConfigurableApplicationContext?context)?{??
  • ????????context.addBeanFactoryPostProcessor(new?ConfigurationWarningsPostProcessor(??
  • ????????????????getChecks()));??
  • ????}??
  • 添加

    PropertySourceOrderingPostProcessor是在ConfigFileApplicationListener執行

    [html]?view plain?copy

  • protected?void?addPostProcessors(ConfigurableApplicationContext?context)?{??
  • ????????context.addBeanFactoryPostProcessor(new?PropertySourceOrderingPostProcessor(??
  • ????????????????context));??
  • ????}??
  • 添加

    來看invokeBeanFactoryPostProcessors方法

    ?

    [html]?view plain?copy

  • public?static?void?invokeBeanFactoryPostProcessors(??
  • ????????????ConfigurableListableBeanFactory?beanFactory,?List<BeanFactoryPostProcessor>?beanFactoryPostProcessors)?{??
  • ??
  • ????????//?Invoke?BeanDefinitionRegistryPostProcessors?first,?if?any.??
  • ????????Set<String>?processedBeans?=?new?HashSet<String>();??
  • ??
  • ????????if?(beanFactory?instanceof?BeanDefinitionRegistry)?{??
  • ????????????...//處理后處理器??
  • ???????????????
  • ????????????String[]?postProcessorNames?=??
  • ????????????????????beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class,?true,?false);??
  • ??
  • ????????????//?First,?invoke?the?BeanDefinitionRegistryPostProcessors?that?implement?PriorityOrdered.??
  • ????????????List<BeanDefinitionRegistryPostProcessor>?priorityOrderedPostProcessors?=?new?ArrayList<BeanDefinitionRegistryPostProcessor>();??
  • ????????????for?(String?ppName?:?postProcessorNames)?{??
  • ????????????????if?(beanFactory.isTypeMatch(ppName,?PriorityOrdered.class))?{??
  • ????????????????????priorityOrderedPostProcessors.add(beanFactory.getBean(ppName,?BeanDefinitionRegistryPostProcessor.class));??
  • ????????????????????processedBeans.add(ppName);??
  • ????????????????}??
  • ????????????}??
  • ????????????OrderComparator.sort(priorityOrderedPostProcessors);??
  • ????????????registryPostProcessors.addAll(priorityOrderedPostProcessors);??
  • ????????????invokeBeanDefinitionRegistryPostProcessors(priorityOrderedPostProcessors,?registry);??
  • ??
  • ????????????//?Next,?invoke?the?BeanDefinitionRegistryPostProcessors?that?implement?Ordered.??
  • ????????????postProcessorNames?=?beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class,?true,?false);??
  • ????????????List<BeanDefinitionRegistryPostProcessor>?orderedPostProcessors?=?new?ArrayList<BeanDefinitionRegistryPostProcessor>();??
  • ????????????for?(String?ppName?:?postProcessorNames)?{??
  • ????????????????if?(!processedBeans.contains(ppName)?&&?beanFactory.isTypeMatch(ppName,?Ordered.class))?{??
  • ????????????????????orderedPostProcessors.add(beanFactory.getBean(ppName,?BeanDefinitionRegistryPostProcessor.class));??
  • ????????????????????processedBeans.add(ppName);??
  • ????????????????}??
  • ????????????}??
  • ????????????OrderComparator.sort(orderedPostProcessors);??
  • ????????????registryPostProcessors.addAll(orderedPostProcessors);??
  • ????????????invokeBeanDefinitionRegistryPostProcessors(orderedPostProcessors,?registry);??
  • ??
  • ????????????//?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))?{??
  • ????????????????????????BeanDefinitionRegistryPostProcessor?pp?=?beanFactory.getBean(ppName,?BeanDefinitionRegistryPostProcessor.class);??
  • ????????????????????????registryPostProcessors.add(pp);??
  • ????????????????????????processedBeans.add(ppName);??
  • ????????????????????????pp.postProcessBeanDefinitionRegistry(registry);??
  • ????????????????????????reiterate?=?true;??
  • ????????????????????}??
  • ????????????????}??
  • ????????????}??
  • ??
  • ????????????//?Now,?invoke?the?postProcessBeanFactory?callback?of?all?processors?handled?so?far?執行后處理器??
  • ????????????invokeBeanFactoryPostProcessors(registryPostProcessors,?beanFactory);??
  • ????????????invokeBeanFactoryPostProcessors(regularPostProcessors,?beanFactory);??
  • ????????}??
  • ?

    ?

    [html]?view plain?copy

  • String[]?postProcessorNames?=?beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class,?true,?false);??
  • 按照bean的類型獲取類型為BeanDefinitionRegistryPostProcessor的bean,這里獲取到的bean名稱為:

    ?

    org.springframework.context.annotation.internalConfigurationAnnotationProcessor;對應的Class為ConfigurationClassPostProcessor

    在前面文章中創建上下文的時候beanfactory創建了該bean。

    經過排序后執行如下方法

    ?

    [html]?view plain?copy

  • invokeBeanDefinitionRegistryPostProcessors(priorityOrderedPostProcessors,?registry);??
  • ?

    ?

    [html]?view plain?copy

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

  • 實際調用ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry

    ?

    ?

    [html]?view plain?copy

  • public?void?postProcessBeanDefinitionRegistry(BeanDefinitionRegistry?registry)?{??
  • ????????...//注冊若干bean??
  • ????????processConfigBeanDefinitions(registry);??
  • ????}??

  • processConfigBeanDefinitions(registry)如下:

    ?

    ?

    [html]?view plain?copy

  • public?void?processConfigBeanDefinitions(BeanDefinitionRegistry?registry)?{??
  • ????????Set<BeanDefinitionHolder>?configCandidates?=?new?LinkedHashSet<BeanDefinitionHolder>();??
  • ????????String[]?candidateNames?=?registry.getBeanDefinitionNames();??
  • ??
  • ????????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));??
  • ????????????}??
  • ????????}??
  • ??
  • ????????//?Return?immediately?if?no?@Configuration?classes?were?found??
  • ????????if?(configCandidates.isEmpty())?{??
  • ????????????return;??
  • ????????}??
  • ??
  • ????????//?Detect?any?custom?bean?name?generation?strategy?supplied?through?the?enclosing?application?context??
  • ????????SingletonBeanRegistry?singletonRegistry?=?null;??
  • ????????if?(registry?instanceof?SingletonBeanRegistry)?{??
  • ????????????singletonRegistry?=?(SingletonBeanRegistry)?registry;??
  • ????????????if?(!this.localBeanNameGeneratorSet?&&?singletonRegistry.containsSingleton(CONFIGURATION_BEAN_NAME_GENERATOR))?{??
  • ????????????????BeanNameGenerator?generator?=?(BeanNameGenerator)?singletonRegistry.getSingleton(CONFIGURATION_BEAN_NAME_GENERATOR);??
  • ????????????????this.componentScanBeanNameGenerator?=?generator;??
  • ????????????????this.importBeanNameGenerator?=?generator;??
  • ????????????}??
  • ????????}??
  • ??
  • ????????//?Parse?each?@Configuration?class??
  • ????????ConfigurationClassParser?parser?=?new?ConfigurationClassParser(??
  • ????????????????this.metadataReaderFactory,?this.problemReporter,?this.environment,??
  • ????????????????this.resourceLoader,?this.componentScanBeanNameGenerator,?registry);??
  • ??
  • ????????Set<ConfigurationClass>?alreadyParsed?=?new?HashSet<ConfigurationClass>(configCandidates.size());??
  • ????????do?{??
  • ????????????parser.parse(configCandidates);??
  • ????????????parser.validate();??
  • ??
  • ????????????Set<ConfigurationClass>?configClasses?=?new?LinkedHashSet<ConfigurationClass>(parser.getConfigurationClasses());??
  • ????????????configClasses.removeAll(alreadyParsed);??
  • ??
  • ????????????//?Read?the?model?and?create?bean?definitions?based?on?its?content??
  • ????????????if?(this.reader?==?null)?{??
  • ????????????????this.reader?=?new?ConfigurationClassBeanDefinitionReader(registry,?this.sourceExtractor,??
  • ????????????????????????this.problemReporter,?this.metadataReaderFactory,?this.resourceLoader,?this.environment,??
  • ????????????????????????this.importBeanNameGenerator,?parser.getImportRegistry());??
  • ????????????}??
  • ????????????this.reader.loadBeanDefinitions(configClasses);??
  • ????????????alreadyParsed.addAll(configClasses);??
  • ??
  • ????????????configCandidates.clear();??
  • ????????????if?(registry.getBeanDefinitionCount()?>?candidateNames.length)?{??
  • ????????????????String[]?newCandidateNames?=?registry.getBeanDefinitionNames();??
  • ????????????????Set<String>?oldCandidateNames?=?new?HashSet<String>(Arrays.asList(candidateNames));??
  • ????????????????Set<String>?alreadyParsedClasses?=?new?HashSet<String>();??
  • ????????????????for?(ConfigurationClass?configurationClass?:?alreadyParsed)?{??
  • ????????????????????alreadyParsedClasses.add(configurationClass.getMetadata().getClassName());??
  • ????????????????}??
  • ????????????????for?(String?candidateName?:?newCandidateNames)?{??
  • ????????????????????if?(!oldCandidateNames.contains(candidateName))?{??
  • ????????????????????????BeanDefinition?beanDef?=?registry.getBeanDefinition(candidateName);??
  • ????????????????????????if?(ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef,?this.metadataReaderFactory)?&&??
  • ????????????????????????????????!alreadyParsedClasses.contains(beanDef.getBeanClassName()))?{??
  • ????????????????????????????configCandidates.add(new?BeanDefinitionHolder(beanDef,?candidateName));??
  • ????????????????????????}??
  • ????????????????????}??
  • ????????????????}??
  • ????????????????candidateNames?=?newCandidateNames;??
  • ????????????}??
  • ????????}??
  • ????????while?(!configCandidates.isEmpty());??
  • ??
  • ????????//?Register?the?ImportRegistry?as?a?bean?in?order?to?support?ImportAware?@Configuration?classes??
  • ????????if?(singletonRegistry?!=?null)?{??
  • ????????????if?(!singletonRegistry.containsSingleton(IMPORT_REGISTRY_BEAN_NAME))?{??
  • ????????????????singletonRegistry.registerSingleton(IMPORT_REGISTRY_BEAN_NAME,?parser.getImportRegistry());??
  • ????????????}??
  • ????????}??
  • ??
  • ????????if?(this.metadataReaderFactory?instanceof?CachingMetadataReaderFactory)?{??
  • ????????????((CachingMetadataReaderFactory)?this.metadataReaderFactory).clearCache();??
  • ????????}??
  • ????}??

  • 又是一段很長的代碼

    ?

    ?

    [html]?view plain?copy

  • String[]?candidateNames?=?registry.getBeanDefinitionNames();??
  • 獲取已經注冊的bean名稱,其信息為:

    ?


    這里看到上一篇中創建的Application對應bean

    ?

    [html]?view plain?copy

  • 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));??
  • ????????????}??
  • ????????}??

  • 判斷對應bean是否為配置文件bean(包含Configuration注解),經過篩選只有Application對應bean滿足條件

    ?

    ?

    [html]?view plain?copy

  • ConfigurationClassParser?parser?=?new?ConfigurationClassParser(??
  • ????????????this.metadataReaderFactory,?this.problemReporter,?this.environment,??
  • ????????????this.resourceLoader,?this.componentScanBeanNameGenerator,?registry);??
  • 該代碼構造了Configuration類解析器

    ?

    執行

    ?

    [html]?view plain?copy

  • parser.parse(configCandidates);??
  • ?

    [html]?view plain?copy

  • public?void?parse(Set<BeanDefinitionHolder>?configCandidates)?{??
  • ????????this.deferredImportSelectors?=?new?LinkedList<DeferredImportSelectorHolder>();??
  • ??
  • ????????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?(Exception?ex)?{??
  • ????????????????throw?new?BeanDefinitionStoreException(??
  • ????????????????????????"Failed?to?parse?configuration?class?["?+?bd.getBeanClassName()?+?"]",?ex);??
  • ????????????}??
  • ????????}??
  • ??
  • ????????processDeferredImportSelectors();??
  • ????}??

  • 調用

    ?

    ?

    [html]?view plain?copy

  • parse(((AnnotatedBeanDefinition)?bd).getMetadata(),?holder.getBeanName());??

  • 最終調用

    ?

    ?

    [html]?view plain?copy

  • protected?void?processConfigurationClass(ConfigurationClass?configClass)?throws?IOException?{??
  • ????????if?(this.conditionEvaluator.shouldSkip(configClass.getMetadata(),?ConfigurationPhase.PARSE_CONFIGURATION))?{??
  • ????????????return;??
  • ????????}??
  • ??
  • ????????ConfigurationClass?existingClass?=?this.configurationClasses.get(configClass);??
  • ????????if?(existingClass?!=?null)?{??
  • ????????????if?(configClass.isImported())?{??
  • ????????????????if?(existingClass.isImported())?{??
  • ????????????????????existingClass.mergeImportedBy(configClass);??
  • ????????????????}??
  • ????????????????//?Otherwise?ignore?new?imported?config?class;?existing?non-imported?class?overrides?it.??
  • ????????????????return;??
  • ????????????}??
  • ????????????else?{??
  • ????????????????//?Explicit?bean?definition?found,?probably?replacing?an?import.??
  • ????????????????//?Let's?remove?the?old?one?and?go?with?the?new?one.??
  • ????????????????this.configurationClasses.remove(configClass);??
  • ????????????????for?(Iterator<ConfigurationClass>?it?=?this.knownSuperclasses.values().iterator();?it.hasNext();?)?{??
  • ????????????????????if?(configClass.equals(it.next()))?{??
  • ????????????????????????it.remove();??
  • ????????????????????}??
  • ????????????????}??
  • ????????????}??
  • ????????}??
  • ??
  • ????????//?Recursively?process?the?configuration?class?and?its?superclass?hierarchy.??
  • ????????SourceClass?sourceClass?=?asSourceClass(configClass);??
  • ????????do?{??
  • ????????????sourceClass?=?doProcessConfigurationClass(configClass,?sourceClass);??
  • ????????}??
  • ????????while?(sourceClass?!=?null);??
  • ??
  • ????????this.configurationClasses.put(configClass,?configClass);??
  • ????}??

  • 首先判斷該bean是否被跳過(該部分代碼上一篇已說明),然后對Class進行包裝,調用sourceClass?= doProcessConfigurationClass(configClass,sourceClass)處理Application類

    ?

    解析Configuration注解

    ?

    [html]?view plain?copy

  • protected?final?SourceClass?doProcessConfigurationClass(ConfigurationClass?configClass,?SourceClass?sourceClass)?throws?IOException?{??
  • ????????//?Recursively?process?any?member?(nested)?classes?first??
  • ????????processMemberClasses(configClass,?sourceClass);??
  • ??
  • ????????//?Process?any?@PropertySource?annotations??
  • ????????for?(AnnotationAttributes?propertySource?:?AnnotationConfigUtils.attributesForRepeatable(??
  • ????????????????sourceClass.getMetadata(),?PropertySources.class,?org.springframework.context.annotation.PropertySource.class))?{??
  • ????????????if?(this.environment?instanceof?ConfigurableEnvironment)?{??
  • ????????????????processPropertySource(propertySource);??
  • ????????????}??
  • ????????????else?{??
  • ????????????????logger.warn("Ignoring?@PropertySource?annotation?on?["?+?sourceClass.getMetadata().getClassName()?+??
  • ????????????????????????"].?Reason:?Environment?must?implement?ConfigurableEnvironment");??
  • ????????????}??
  • ????????}??
  • ??
  • ????????//?Process?any?@ComponentScan?annotations??
  • ????????AnnotationAttributes?componentScan?=?AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(),?ComponentScan.class);??
  • ????????if?(componentScan?!=?null?&&?!this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(),?ConfigurationPhase.REGISTER_BEAN))?{??
  • ????????????//?The?config?class?is?annotated?with?@ComponentScan?->?perform?the?scan?immediately??
  • ????????????Set<BeanDefinitionHolder>?scannedBeanDefinitions?=??
  • ????????????????????this.componentScanParser.parse(componentScan,?sourceClass.getMetadata().getClassName());??
  • ????????????//?Check?the?set?of?scanned?definitions?for?any?further?config?classes?and?parse?recursively?if?necessary??
  • ????????????for?(BeanDefinitionHolder?holder?:?scannedBeanDefinitions)?{??
  • ????????????????if?(ConfigurationClassUtils.checkConfigurationClassCandidate(holder.getBeanDefinition(),?this.metadataReaderFactory))?{??
  • ????????????????????parse(holder.getBeanDefinition().getBeanClassName(),?holder.getBeanName());??
  • ????????????????}??
  • ????????????}??
  • ????????}??
  • ??
  • ????????//?Process?any?@Import?annotations??
  • ????????processImports(configClass,?sourceClass,?getImports(sourceClass),?true);??
  • ??
  • ????????//?Process?any?@ImportResource?annotations??
  • ????????if?(sourceClass.getMetadata().isAnnotated(ImportResource.class.getName()))?{??
  • ????????????AnnotationAttributes?importResource?=?AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(),?ImportResource.class);??
  • ????????????String[]?resources?=?importResource.getStringArray("value");??
  • ????????????Class<??extends?BeanDefinitionReader>?readerClass?=?importResource.getClass("reader");??
  • ????????????for?(String?resource?:?resources)?{??
  • ????????????????String?resolvedResource?=?this.environment.resolveRequiredPlaceholders(resource);??
  • ????????????????configClass.addImportedResource(resolvedResource,?readerClass);??
  • ????????????}??
  • ????????}??
  • ??
  • ????????//?Process?individual?@Bean?methods??
  • ????????Set<MethodMetadata>?beanMethods?=?sourceClass.getMetadata().getAnnotatedMethods(Bean.class.getName());??
  • ????????for?(MethodMetadata?methodMetadata?:?beanMethods)?{??
  • ????????????configClass.addBeanMethod(new?BeanMethod(methodMetadata,?configClass));??
  • ????????}??
  • ??
  • ????????//?Process?superclass,?if?any??
  • ????????if?(sourceClass.getMetadata().hasSuperClass())?{??
  • ????????????String?superclass?=?sourceClass.getMetadata().getSuperClassName();??
  • ????????????if?(!superclass.startsWith("java")?&&?!this.knownSuperclasses.containsKey(superclass))?{??
  • ????????????????this.knownSuperclasses.put(superclass,?configClass);??
  • ????????????????//?Superclass?found,?return?its?annotation?metadata?and?recurse??
  • ????????????????return?sourceClass.getSuperClass();??
  • ????????????}??
  • ????????}??
  • ??
  • ????????//?No?superclass?->?processing?is?complete??
  • ????????return?null;??
  • ????}??

  • 到這里就看到了如何去解析Application類

    ?

    ?

    [html]?view plain?copy

  • processMemberClasses(configClass,?sourceClass);??
  • 處理其中內部類,解析內部類的過程和外部類相似,因此繼續看下面的代碼

    ?

    處理PropertySource注解

    ?

    [html]?view plain?copy

  • //?Process?any?@PropertySource?annotations??
  • ????????for?(AnnotationAttributes?propertySource?:?AnnotationConfigUtils.attributesForRepeatable(??
  • ????????????????sourceClass.getMetadata(),?PropertySources.class,?org.springframework.context.annotation.PropertySource.class))?{??
  • ????????????if?(this.environment?instanceof?ConfigurableEnvironment)?{??
  • ????????????????processPropertySource(propertySource);??
  • ????????????}??
  • ????????????else?{??
  • ????????????????logger.warn("Ignoring?@PropertySource?annotation?on?["?+?sourceClass.getMetadata().getClassName()?+??
  • ????????????????????????"].?Reason:?Environment?must?implement?ConfigurableEnvironment");??
  • ????????????}??
  • ????????}<pre?name="code"?class="html">??
  • [html]?view plain?copy

  • ??
  • ?

    ?

    ?

    ?

    其核心操作:

    ?

    [html]?view plain?copy

  • private?void?processPropertySource(AnnotationAttributes?propertySource)?throws?IOException?{??
  • ????????String?name?=?propertySource.getString("name");??
  • ????????String[]?locations?=?propertySource.getStringArray("value");??
  • ????????boolean?ignoreResourceNotFound?=?propertySource.getBoolean("ignoreResourceNotFound");??
  • ????????Assert.isTrue(locations.length?>?0,?"At?least?one?@PropertySource(value)?location?is?required");??
  • ????????for?(String?location?:?locations)?{??
  • ????????????try?{??
  • ????????????????String?resolvedLocation?=?this.environment.resolveRequiredPlaceholders(location);??
  • ????????????????Resource?resource?=?this.resourceLoader.getResource(resolvedLocation);??
  • ????????????????ResourcePropertySource?rps?=?(StringUtils.hasText(name)????
  • ????????????????????????new?ResourcePropertySource(name,?resource)?:?new?ResourcePropertySource(resource));??
  • ????????????????addPropertySource(rps);??
  • ????????????}??
  • ????????????catch?(IllegalArgumentException?ex)?{??
  • ????????????????//?from?resolveRequiredPlaceholders??
  • ????????????????if?(!ignoreResourceNotFound)?{??
  • ????????????????????throw?ex;??
  • ????????????????}??
  • ????????????}??
  • ????????????catch?(FileNotFoundException?ex)?{??
  • ????????????????//?from?ResourcePropertySource?constructor??
  • ????????????????if?(!ignoreResourceNotFound)?{??
  • ????????????????????throw?ex;??
  • ????????????????}??
  • ????????????}??
  • ????????}??
  • ????}??
  • 通過注解中的信息獲取資源信息,然后添加到MutablePropertySourcespropertySources?= ((ConfigurableEnvironment)this.environment).getPropertySources()中,該內容前面已有講述

    ?

    解析ComponentScan注解

    ?

    [html]?view plain?copy

  • //?Process?any?@ComponentScan?annotations??
  • ????????AnnotationAttributes?componentScan?=?AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(),?ComponentScan.class);??
  • ????????if?(componentScan?!=?null?&&?!this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(),?ConfigurationPhase.REGISTER_BEAN))?{??
  • ????????????//?The?config?class?is?annotated?with?@ComponentScan?->?perform?the?scan?immediately??
  • ????????????Set<BeanDefinitionHolder>?scannedBeanDefinitions?=??
  • ????????????????????this.componentScanParser.parse(componentScan,?sourceClass.getMetadata().getClassName());??
  • ????????????//?Check?the?set?of?scanned?definitions?for?any?further?config?classes?and?parse?recursively?if?necessary??
  • ????????????for?(BeanDefinitionHolder?holder?:?scannedBeanDefinitions)?{??
  • ????????????????if?(ConfigurationClassUtils.checkConfigurationClassCandidate(holder.getBeanDefinition(),?this.metadataReaderFactory))?{??
  • ????????????????????parse(holder.getBeanDefinition().getBeanClassName(),?holder.getBeanName());??
  • ????????????????}??
  • ????????????}??
  • ????????}??
  • ComponentScan注解的作用大家都明白,掃描執行路徑下bean信息,那么具體是如何實現的?需要跟進去看代碼,調用

    ?

    ?

    [html]?view plain?copy

  • Set<BeanDefinitionHolder>?scannedBeanDefinitions?=??
  • ????????????????????this.componentScanParser.parse(componentScan,?sourceClass.getMetadata().getClassName());??
  • ?

    [html]?view plain?copy

  • public?Set<BeanDefinitionHolder>?parse(AnnotationAttributes?componentScan,?final?String?declaringClass)?{??
  • ?????????...//通過注解中的信息設置掃描器的參數信息??
  • ????????return?scanner.doScan(StringUtils.toStringArray(basePackages));??
  • ????}??

  • 代碼中忽略了掃描器對應的參數信息,直接看doScan方法

    ?

    ?

    [html]?view plain?copy

  • protected?Set<BeanDefinitionHolder>?doScan(String...?basePackages)?{??
  • ????Assert.notEmpty(basePackages,?"At?least?one?base?package?must?be?specified");??
  • ????Set<BeanDefinitionHolder>?beanDefinitions?=?new?LinkedHashSet<BeanDefinitionHolder>();??
  • ????for?(String?basePackage?:?basePackages)?{??
  • ????????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)?{??
  • ????????????????postProcessBeanDefinition((AbstractBeanDefinition)?candidate,?beanName);??
  • ????????????}??
  • ????????????if?(candidate?instanceof?AnnotatedBeanDefinition)?{??
  • ????????????????AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition)?candidate);??
  • ????????????}??
  • ????????????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;??
  • }??
  • 遍歷basePackages信息,

    [html]?view plain?copy

  • Set<BeanDefinition>?candidates?=?findCandidateComponents(basePackage);??
  • 查詢類路徑下申明的組件信息,

    [html]?view plain?copy

  • public?Set<BeanDefinition>?findCandidateComponents(String?basePackage)?{??
  • ????????Set<BeanDefinition>?candidates?=?new?LinkedHashSet<BeanDefinition>();??
  • ????????try?{??
  • ????????????String?packageSearchPath?=?ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX?+??
  • ????????????????????resolveBasePackage(basePackage)?+?"/"?+?this.resourcePattern;??
  • ????????????Resource[]?resources?=?this.resourcePatternResolver.getResources(packageSearchPath);??
  • ????????????boolean?traceEnabled?=?logger.isTraceEnabled();??
  • ????????????boolean?debugEnabled?=?logger.isDebugEnabled();??
  • ????????????for?(Resource?resource?:?resources)?{??
  • ????????????????if?(traceEnabled)?{??
  • ????????????????????logger.trace("Scanning?"?+?resource);??
  • ????????????????}??
  • ????????????????if?(resource.isReadable())?{??
  • ????????????????????try?{??
  • ????????????????????????MetadataReader?metadataReader?=?this.metadataReaderFactory.getMetadataReader(resource);??
  • ????????????????????????if?(isCandidateComponent(metadataReader))?{??
  • ????????????????????????????ScannedGenericBeanDefinition?sbd?=?new?ScannedGenericBeanDefinition(metadataReader);??
  • ????????????????????????????sbd.setResource(resource);??
  • ????????????????????????????sbd.setSource(resource);??
  • ????????????????????????????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?(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;??
  • ????}??
  • ?

    ?

    [html]?view plain?copy

  • Resource[]?resources?=?this.resourcePatternResolver.getResources(packageSearchPath);??
  • ?

    ?

    ?

    [html]?view plain?copy

  • public?Resource[]?getResources(String?locationPattern)?throws?IOException?{??
  • ????????Assert.notNull(locationPattern,?"Location?pattern?must?not?be?null");??
  • ????????if?(locationPattern.startsWith(CLASSPATH_ALL_URL_PREFIX))?{??
  • ????????????//?a?class?path?resource?(multiple?resources?for?same?name?possible)??
  • ????????????if?(getPathMatcher().isPattern(locationPattern.substring(CLASSPATH_ALL_URL_PREFIX.length())))?{??
  • ????????????????//?a?class?path?resource?pattern??
  • ????????????????return?findPathMatchingResources(locationPattern);??
  • ????????????}??
  • ????????????else?{??
  • ????????????????//?all?class?path?resources?with?the?given?name??
  • ????????????????return?findAllClassPathResources(locationPattern.substring(CLASSPATH_ALL_URL_PREFIX.length()));??
  • ????????????}??
  • ????????}??
  • ????????else?{??
  • ????????????//?Only?look?for?a?pattern?after?a?prefix?here??
  • ????????????//?(to?not?get?fooled?by?a?pattern?symbol?in?a?strange?prefix).??
  • ????????????int?prefixEnd?=?locationPattern.indexOf(":")?+?1;??
  • ????????????if?(getPathMatcher().isPattern(locationPattern.substring(prefixEnd)))?{??
  • ????????????????//?a?file?pattern??
  • ????????????????return?findPathMatchingResources(locationPattern);??
  • ????????????}??
  • ????????????else?{??
  • ????????????????//?a?single?resource?with?the?given?name??
  • ????????????????return?new?Resource[]?{getResourceLoader().getResource(locationPattern)};??
  • ????????????}??
  • ????????}??
  • ????}??
  • ?

    ?

    解析路徑信息,這里spring有自己的一套繼續規則,通過findPathMatchingResources()檢索到指定類路徑下所有的*.class文件,然后調用findAllClassPathResources解析Class文件

    ?

    [html]?view plain?copy

  • protected?Resource[]?findAllClassPathResources(String?location)?throws?IOException?{??
  • ????????String?path?=?location;??
  • ????????if?(path.startsWith("/"))?{??
  • ????????????path?=?path.substring(1);??
  • ????????}??
  • ????????Set<Resource>?result?=?doFindAllClassPathResources(path);??
  • ????????return?result.toArray(new?Resource[result.size()]);??
  • ????}??
  • ?

    [html]?view plain?copy

  • protected?Set<Resource>?doFindAllClassPathResources(String?path)?throws?IOException?{??
  • ????????Set<Resource>?result?=?new?LinkedHashSet<Resource>(16);??
  • ????????ClassLoader?cl?=?getClassLoader();??
  • ????????Enumeration<URL>?resourceUrls?=?(cl?!=?null???cl.getResources(path)?:?ClassLoader.getSystemResources(path));??
  • ????????while?(resourceUrls.hasMoreElements())?{??
  • ????????????URL?url?=?resourceUrls.nextElement();??
  • ????????????result.add(convertClassLoaderURL(url));??
  • ????????}??
  • ????????if?("".equals(path))?{??
  • ????????????//?The?above?result?is?likely?to?be?incomplete,?i.e.?only?containing?file?system?references.??
  • ????????????//?We?need?to?have?pointers?to?each?of?the?jar?files?on?the?classpath?as?well...??
  • ????????????addAllClassLoaderJarRoots(cl,?result);??
  • ????????}??
  • ????????return?result;??
  • ????}??

  • 通過上面的代碼可以發現,在獲取到path路徑以后spring采用類加載器獲取指定Class文件對應的資源信息

    ?

    ?

    獲取完資源信息后調用

    ?

    [html]?view plain?copy

  • MetadataReader?metadataReader?=?this.metadataReaderFactory.getMetadataReader(resource);??
  • 解析資源信息對應的元數據

    ?

    ?

    ?

    [html]?view plain?copy

  • if?(isCandidateComponent(metadataReader))?{??
  • ????????????????????????????ScannedGenericBeanDefinition?sbd?=?new?ScannedGenericBeanDefinition(metadataReader);??
  • ????????????????????????????sbd.setResource(resource);??
  • ????????????????????????????sbd.setSource(resource);??
  • ????????????????????????????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);??
  • ????????????????????????????}??
  • ????????????????????????}??
  • 如果存在Componment注解修飾的Class文件則加入到BeanDefinition集合中返回。

    ?

    ?

    回到調用掃描bean處

    ?

    [html]?view plain?copy

  • for?(BeanDefinitionHolder?holder?:?scannedBeanDefinitions)?{??
  • ????????????????if?(ConfigurationClassUtils.checkConfigurationClassCandidate(holder.getBeanDefinition(),?this.metadataReaderFactory))?{??
  • ????????????????????parse(holder.getBeanDefinition().getBeanClassName(),?holder.getBeanName());??
  • ????????????????}??
  • ????????????}??

  • 遍歷掃描到的bean信息,如果為配置bean,則執行parse方法,該方法調用processConfigurationClass,形成一個遞歸的操作。

    ?

    解析Import注解

    ?

    [html]?view plain?copy

  • processImports(configClass,?sourceClass,?getImports(sourceClass),?true);
  • ?

    處理import注解,該注解在spring boot中使用非常頻繁

    ?

    [html]?view plain?copy

  • private?void?processImports(ConfigurationClass?configClass,?SourceClass?currentSourceClass,??
  • ????????????Collection<SourceClass>?importCandidates,?boolean?checkForCircularImports)?throws?IOException?{??
  • ??
  • ?????????...??
  • ???????????
  • ????????????this.importStack.push(configClass);??
  • ????????????try?{??
  • ????????????????for?(SourceClass?candidate?:?importCandidates)?{??
  • ????????????????????if?(candidate.isAssignable(ImportSelector.class))?{??
  • ????????????????????????//?Candidate?class?is?an?ImportSelector?->?delegate?to?it?to?determine?imports??
  • ????????????????????????Class<?>?candidateClass?=?candidate.loadClass();??
  • ????????????????????????ImportSelector?selector?=?BeanUtils.instantiateClass(candidateClass,?ImportSelector.class);??
  • ????????????????????????invokeAwareMethods(selector);??
  • ????????????????????????if?(this.deferredImportSelectors?!=?null?&&?selector?instanceof?DeferredImportSelector)?{??
  • ????????????????????????????this.deferredImportSelectors.add(??
  • ????????????????????????????????????new?DeferredImportSelectorHolder(configClass,?(DeferredImportSelector)?selector));??
  • ????????????????????????}??
  • ????????????????????????else?{??
  • ????????????????????????????String[]?importClassNames?=?selector.selectImports(currentSourceClass.getMetadata());??
  • ????????????????????????????Collection<SourceClass>?importSourceClasses?=?asSourceClasses(importClassNames);??
  • ????????????????????????????processImports(configClass,?currentSourceClass,?importSourceClasses,?false);??
  • ????????????????????????}??
  • ????????????????????}??
  • ????????????????????else?if?(candidate.isAssignable(ImportBeanDefinitionRegistrar.class))?{??
  • ????????????????????????//?Candidate?class?is?an?ImportBeanDefinitionRegistrar?->??
  • ????????????????????????//?delegate?to?it?to?register?additional?bean?definitions??
  • ????????????????????????Class<?>?candidateClass?=?candidate.loadClass();??
  • ????????????????????????ImportBeanDefinitionRegistrar?registrar?=??
  • ????????????????????????????????BeanUtils.instantiateClass(candidateClass,?ImportBeanDefinitionRegistrar.class);??
  • ????????????????????????invokeAwareMethods(registrar);??
  • ????????????????????????configClass.addImportBeanDefinitionRegistrar(registrar,?currentSourceClass.getMetadata());??
  • ????????????????????}??
  • ????????????????????else?{??
  • ????????????????????????//?Candidate?class?not?an?ImportSelector?or?ImportBeanDefinitionRegistrar?->??
  • ????????????????????????//?process?it?as?an?@Configuration?class??
  • ????????????????????????this.importStack.registerImport(??
  • ????????????????????????????????currentSourceClass.getMetadata(),?candidate.getMetadata().getClassName());??
  • ????????????????????????processConfigurationClass(candidate.asConfigClass(configClass));??
  • ????????????????????}??
  • ????????????????}??
  • ????????????}??
  • ????????????catch?(BeanDefinitionStoreException?ex)?{??
  • ????????????????throw?ex;??
  • ????????????}??
  • ????????????catch?(Exception?ex)?{??
  • ????????????????throw?new?BeanDefinitionStoreException("Failed?to?process?import?candidates?for?configuration?class?["?+??
  • ????????????????????????configClass.getMetadata().getClassName()?+?"]",?ex);??
  • ????????????}??
  • ????????????finally?{??
  • ????????????????this.importStack.pop();??
  • ????????????}??
  • ????????}??
  • ????}??
  • 如果Import注解中Class為ImportSelector子類,通過invokeAwareMethods(selector)設置aware值,如果類型為DeferredImportSelector則添加到deferredImportSelectors集合中,待前面的parser.parse(configCandidates)

    ?

    方法中processDeferredImportSelectors()處理;如果不是,則執行selectImports方法,將獲取到的結果遞歸調用processImports,解析selectImports得到的結果

    如果Import注解中Class為ImportBeanDefinitionRegistrar子類,則添加到importBeanDefinitionRegistrars中,注意該部分的數據在執行完parser.parse(configCandidates)后調用this.reader.loadBeanDefinitions(configClasses)解析

    否則執行配置信息的解析操作。

    ?

    解析ImportResource注解

    ?

    [html]?view plain?copy

  • //?Process?any?@ImportResource?annotations??
  • ????????if?(sourceClass.getMetadata().isAnnotated(ImportResource.class.getName()))?{??
  • ????????????AnnotationAttributes?importResource?=?AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(),?ImportResource.class);??
  • ????????????String[]?resources?=?importResource.getStringArray("value");??
  • ????????????Class<??extends?BeanDefinitionReader>?readerClass?=?importResource.getClass("reader");??
  • ????????????for?(String?resource?:?resources)?{??
  • ????????????????String?resolvedResource?=?this.environment.resolveRequiredPlaceholders(resource);??
  • ????????????????configClass.addImportedResource(resolvedResource,?readerClass);??
  • ????????????}??
  • ????????}??
  • ?

    ?

    解析Bean注解

    ?

    [html]?view plain?copy

  • Set<MethodMetadata>?beanMethods?=?sourceClass.getMetadata().getAnnotatedMethods(Bean.class.getName());??
  • ????????for?(MethodMetadata?methodMetadata?:?beanMethods)?{??
  • ????????????configClass.addBeanMethod(new?BeanMethod(methodMetadata,?configClass));??
  • ????????}??
  • ?

    ?

    上面這兩個注解相對來講要簡單一些,至此bean的解析完成,這里面涉及到多重遞歸,首先理清楚一條線才能把代碼看明白。

    總結

    以上是生活随笔為你收集整理的spring boot实战(第十篇)Spring boot Bean加载源码分析的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。