日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

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

javascript

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

發布時間:2025/3/21 javascript 49 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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加载源码分析的全部內容,希望文章能夠幫你解決所遇到的問題。

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

    国产精品一区二区三区观看 | 国产精品wwwwww | 亚洲午夜精品久久久久久久久久久久 | 人人操日日干 | 亚洲开心激情 | 一区二区三区视频网站 | 婷婷色综合色 | 色先锋av资源中文字幕 | 91pony九色丨交换 | 男女视频国产 | 日韩色一区二区三区 | 欧美 日韩 视频 | 久久久国产精品亚洲一区 | 亚洲精品高清在线观看 | 国产一区在线视频 | 久久怡红院 | 国产字幕在线观看 | 久草网站 | 色的网站在线观看 | 精品国产自在精品国产精野外直播 | 日韩中文字幕免费视频 | 人人爽人人插 | 99热这里有| 日日操天天爽 | 国产精品美女久久久 | 69亚洲精品 | 中文字幕在线观看三区 | 超碰夜夜 | 日韩3区| 最新国产中文字幕 | 中文字幕91在线 | 天天射,天天干 | 五月天久久狠狠 | 国产va饥渴难耐女保洁员在线观看 | 2019免费中文字幕 | 国产专区视频 | www.天天干.com | 国产中文字幕大全 | 最新av网址大全 | 中文永久免费观看 | 韩国av一区二区三区在线观看 | 免费在线观看av不卡 | jizz18欧美18 | 92国产精品久久久久首页 | 久久久精品日本 | 天天操夜夜做 | 久久99热这里只有精品 | 久草在线费播放视频 | 精品99在线 | 女人久久久久 | 91精品国自产在线 | 国产性天天综合网 | 久久99国产精品久久99 | 日韩免费看视频 | 久久手机精品视频 | 五月天视频网 | 日韩精品中文字幕av | 不卡的av电影在线观看 | 国产精品美女免费看 | 在线观看免费色 | 中文字幕一区2区3区 | 夜夜操天天 | 亚洲欧洲xxxx | 日韩视频一区二区三区 | 精品久久美女 | av网站免费线看精品 | 国产成人一区二区三区久久精品 | 美女视频免费精品 | 99精品乱码国产在线观看 | 欧美日韩精品免费观看视频 | 久久高清av | 国产精品理论片在线播放 | 91久久国产自产拍夜夜嗨 | 2024国产精品视频 | 婷婷色婷婷 | 91视频专区 | 激情五月婷婷激情 | 国产在线综合视频 | 天天插伊人 | 国产精品美乳一区二区免费 | 国产精品18久久久久白浆 | 日韩久久午夜一级啪啪 | 久久久久女人精品毛片 | 欧美日韩另类在线观看 | 美女一级毛片视频 | 操操日日 | 成人黄色在线观看视频 | 91香蕉视频 | 四虎成人网 | 在线黄色国产 | 亚洲第二色 | 91福利免费 | 久久精品国产免费看久久精品 | 国产高清精品在线观看 | 狠狠操天天射 | 午夜三级福利 | 久久久国产99久久国产一 | 久久96| 国际精品久久久 | 天天干天天做 | av电影久久 | 亚洲国内精品 | 天天操天操 | 久久99久久99精品免视看婷婷 | 久久国产精品久久久 | 91av色 | 欧洲高潮三级做爰 | 欧美在线观看视频一区二区 | 国产小视频在线免费观看 | 人人精品久久 | 九九精品视频在线观看 | 国产精品久久久久久久婷婷 | 国产高清中文字幕 | 91在线播放视频 | 久久精品视频国产 | 91看片淫黄大片在线播放 | 免费十分钟 | 97人人澡人人添人人爽超碰 | 国产无区一区二区三麻豆 | 日本中文字幕在线观看 | 日韩理论在线 | 最新午夜电影 | 亚洲精品成人网 | 亚洲狠狠操 | 99精品乱码国产在线观看 | 亚在线播放中文视频 | 日韩电影一区二区三区在线观看 | 色综合天天天天做夜夜夜夜做 | 亚洲区视频在线 | www.av免费观看 | 久久久久久久99 | 婷婷精品国产欧美精品亚洲人人爽 | 九色精品免费永久在线 | 五月天婷亚洲天综合网精品偷 | 国产午夜精品一区二区三区在线观看 | 国产在线播放观看 | 国产美女视频免费 | 九九精品在线观看 | 视频一区久久 | 五月天色网站 | 国产精品乱码高清在线看 | 欧美在线视频一区二区三区 | 丁香婷婷激情国产高清秒播 | 国产精品区二区三区日本 | 亚洲综合成人婷婷小说 | 亚洲无人区小视频 | 午夜av在线免费 | av五月婷婷 | 二区在线播放 | 91视频88av | 日韩高清一区二区 | 欧美日韩精品区 | 日韩免费在线观看网站 | 亚洲视频,欧洲视频 | 亚洲成人av在线播放 | 亚洲一区二区三区四区精品 | 欧美 亚洲 另类 激情 另类 | 中文字幕免费观看视频 | 久久涩涩网站 | 国产精品网站一区二区三区 | 亚洲女同videos | 亚洲区视频在线 | .国产精品成人自产拍在线观看6 | 蜜桃视频精品 | 久久久久久久久久久久久久免费看 | 欧美成年人在线视频 | 久久天堂亚洲 | 碰超在线97人人 | 日韩精品一区二区三区不卡 | 欧美成人高清 | 精品亚洲男同gayvideo网站 | 久久视讯| 亚洲欧美日韩国产一区二区 | 久久久久久免费 | 国产一区国产二区在线观看 | 综合久久五月天 | 久久av中文字幕片 | 欧洲色综合 | 久草网在线视频 | 四虎国产精品免费 | 日韩欧美一级二级 | 日韩在线高清免费视频 | 在线观看mv的中文字幕网站 | 亚洲视频久久 | 国产精品一区二区三区在线看 | 全黄网站 | 成人a毛片| 色综合久久综合 | 91c网站色版视频 | 99久久99精品 | 欧美性生活小视频 | 国产资源免费在线观看 | 国产一级淫片在线观看 | 国产成人福利在线观看 | 亚洲成年片 | 97在线成人 | 亚洲国产精品成人av | 国产原创在线 | 中文字幕在线视频国产 | 中文国产成人精品久久一 | 亚洲成人xxx | 五月激情丁香 | 欧美资源在线观看 | 91在线播放国产 | 在线精品视频免费观看 | 麻豆视频免费在线 | 人人射人人爽 | 国内精品久久久 | 在线国产日本 | 人人爽人人爽人人片av免 | 91福利在线导航 | 国产成人精品久久亚洲高清不卡 | 69精品在线观看 | 久久在线免费 | 欧美在线观看小视频 | 久久久天天操 | 亚洲在线高清 | 午夜视频免费在线观看 | 久久精品爱视频 | 亚洲精品一区二区三区四区高清 | 午夜视频在线观看一区 | 91午夜精品 | 国产精品99久久久久久久久 | 国内精品小视频 | 色资源中文字幕 | 日韩中文字幕一区 | 久久视频一区 | 欧美日韩视频观看 | 免费看污在线观看 | 97超级碰碰碰碰久久久久 | 国产精品久久久久久久久久了 | 一区二区理论片 | 一级性生活片 | 天天插夜夜操 | 98超碰在线 | 亚洲美女精品 | 精品1区2区| 欧美91视频| 国产69精品久久久久久久久久 | 亚洲欧美综合精品久久成人 | 丁香六月五月婷婷 | av一区二区三区在线观看 | 日韩a级免费视频 | 91视频麻豆视频 | 韩国一区二区在线观看 | 久久久人人人 | 国产精品九九久久久久久久 | 一区二区中文字幕在线观看 | 免费日p视频 | 韩国视频一区二区三区 | 青春草视频在线播放 | 一区二区中文字幕在线 | 成人在线观看免费 | 亚洲成a人片77777潘金莲 | 日韩中文字幕视频在线 | 午夜久久久久 | 久久精品二区 | 91麻豆精品国产 | 全久久久久久久久久久电影 | 中文字幕91 | 天天操天天舔天天爽 | 日韩av电影中文字幕在线观看 | 亚洲精品一区二区三区四区高清 | 欧美91视频 | 色丁香婷婷 | 日韩91精品| 丁香六月久久综合狠狠色 | a在线视频v视频 | 久久精品电影 | 午夜视频一区二区三区 | 欧美做受xxx | 草久草久 | 91精品国产欧美一区二区成人 | 欧美一区二区在线免费观看 | 香蕉视频久久 | 日日碰狠狠躁久久躁综合网 | www.777奇米| 国产老妇av | 国产a网站 | 国产免费a | 免费黄色在线播放 | 最新影院 | 成人免费看电影 | 中文字幕视频 | 久草精品在线播放 | 日韩欧美在线中文字幕 | 永久黄网站色视频免费观看w | 在线日韩av | 亚洲男女精品 | 天天操天天添 | 久热色超碰 | 日韩一级电影网站 | 日韩精品免费一线在线观看 | 亚洲精品中文字幕在线观看 | av一区二区三区在线播放 | 五月婷婷欧美 | aaa日本高清在线播放免费观看 | 国产资源在线免费观看 | 久草在线视频首页 | 色五丁香 | 亚洲成人资源在线观看 | 中字幕视频在线永久在线观看免费 | 亚洲成a人片综合在线 | 97国产情侣爱久久免费观看 | 久久久久久美女 | 欧美性极品xxxx娇小 | 国产一区二区三区午夜 | 国产精品免费一区二区 | 天天爱综合| 亚洲在线网址 | 欧美性性网 | 亚洲国产福利视频 | 精品国产一区在线观看 | 国产做aⅴ在线视频播放 | 新版资源中文在线观看 | 亚洲精品乱码久久久久久蜜桃动漫 | 一区二区三区日韩在线观看 | 亚洲国产精品99久久久久久久久 | www免费| www天天操| 2019天天干天天色 | 国产一级视频在线免费观看 | 精品国产伦一区二区三区免费 | 五月婷婷丁香在线观看 | 亚洲国产午夜精品 | 国产日韩欧美在线观看视频 | 综合国产在线观看 | 中文在线中文资源 | 日韩成人xxxx | 久久99视频免费观看 | 久久精国产 | 日韩在线观看视频在线 | 日日躁天天躁 | 在线观看www视频 | 99久久精品久久久久久动态片 | 国产成人精品一区二区三区在线 | 日韩在线中文字幕视频 | 久久综合一本 | 另类老妇性bbwbbw高清 | 麻豆视频在线免费观看 | 中文字幕在线观看完整 | av片在线观看免费 | 91资源在线播放 | 日韩欧美高清一区二区 | 国产特级毛片aaaaaa毛片 | 精品uu | 中文字幕色综合网 | 国产亚洲精品久久久久久大师 | 久久桃花网 | 99久久激情 | 欧美极品少妇xbxb性爽爽视频 | 久久国产麻豆 | 精品国产不卡 | 欧美欧美 | 国产亚洲资源 | 国产美女无遮挡永久免费 | 免费a网 | 人人爱爱 | www日韩精品 | 三上悠亚一区二区在线观看 | 婷婷丁香色综合狠狠色 | 欧美午夜理伦三级在线观看 | 日韩最新在线 | 亚洲作爱| 久久男人影院 | av免费电影网站 | 在线三级av | 欧美日韩中文国产 | www免费网站在线观看 | 97理论片 | 99免费看片 | 九九九在线 | 丝袜美女视频网站 | 亚洲一一在线 | 日韩免费在线视频观看 | 国产精品久久久久免费 | 91av短视频| 日本中文一区二区 | 久久国产网站 | 91在线麻豆 | 黄色特一级片 | 久久国产一区 | 人人草天天草 | 欧美资源 | 日韩艹 | 丁香六月激情 | 中文字幕一区二区三区在线视频 | 精品高清美女精品国产区 | 91资源在线播放 | 特级毛片在线观看 | 久久成人午夜 | 97激情影院 | 国产精品白丝jk白祙 | 日韩69视频 | 国产精品视频线看 | 久久这里只有精品久久 | 久久成人精品 | 午夜精品久久久久99热app | 国产99区| 天堂入口网站 | 五月婷婷.com| 欧美日韩在线观看视频 | 日韩综合精品 | 久久人人爽人人爽人人片 | 欧洲精品码一区二区三区免费看 | www..com黄色片 | 97电影在线| 久久精品123| 日韩高清国产精品 | 四虎视频| 成人免费亚洲 | 亚洲永久精品在线观看 | av一区二区三区在线播放 | 国产精品大全 | 欧洲高潮三级做爰 | 国产一区二三区好的 | 亚洲狠狠干 | 国产看片 色 | www.少妇 | 国产一性一爱一乱一交 | 日韩成人免费观看 | 国产美女无遮挡永久免费 | 人人插人人干 | 日批视频在线 | 成人在线一区二区三区 | 一区二区三区免费在线观看视频 | 日韩久久一区 | 欧美不卡视频在线 | 日韩动态视频 | 国产精品美女在线 | 日韩免费视频一区二区 | www久久com| 亚洲无线视频 | 色综合天天爱 | 国产精品久久久久久久久久妇女 | 久久午夜鲁丝片 | 一区二区三区中文字幕在线 | 97超碰人人澡人人爱 | 国产第一页在线观看 | 中文字幕视频在线播放 | 色片网站在线观看 | 黄色在线免费观看网址 | 97超碰免费在线观看 | 亚洲欧美视频在线观看 | 免费福利片 | 欧美精品久久久久久久久免 | 亚洲美女免费视频 | 九九九热精品免费视频观看 | av网址在线播放 | 久久综合久久综合这里只有精品 | 亚洲国产精品久久久久婷婷884 | 高清av在线免费观看 | 18网站在线观看 | 2019av在线视频| 中文字幕一区二区三区四区视频 | 中文字幕欲求不满 | 久久精彩免费视频 | 精品久久久久久一区二区里番 | 国产专区日韩专区 | 色999精品| 亚洲精品欧美成人 | 久久香蕉国产精品麻豆粉嫩av | 亚洲精品国产精品国自产在线 | 插插插色综合 | 国产极品尤物在线 | 国产精品毛片一区视频 | 在线观看中文av | 欧美性生活免费看 | 香蕉久久国产 | 色播99| 丁香国产视频 | 精品女同一区二区三区在线观看 | 色综合亚洲精品激情狠狠 | 久久久影视 | 国产123av| 久久久久一区二区三区 | 韩日av在线| 欧美专区日韩专区 | www.99热精品 | 日韩色中色 | 国产精品久久久久久久婷婷 | 中文字幕免费观看全部电影 | 日韩在线观看视频一区二区三区 | 在线观看av不卡 | 中文av网 | 91精品国自产在线 | 欧美最猛性xxx | 日p视频在线观看 | 久久久久久免费 | 日韩r级在线 | 视频一区久久 | 亚洲作爱视频 | 国产aaa大片 | 天堂av中文字幕 | 国产九色在线播放九色 | 久久国产影院 | 国产精品网红直播 | 天天色棕合合合合合合 | 免费国产一区二区 | 狠狠色丁香婷婷综合基地 | 97在线观看视频免费 | 国产午夜精品一区二区三区欧美 | 午夜av大片| 国产成人精品日本亚洲999 | 国产成人无码AⅤ片在线观 日韩av不卡在线 | 五月激情综合婷婷 | 久久久久中文字幕 | adn—256中文在线观看 | 国产视频在线看 | 国产成人精品一二三区 | 国产精品久久9 | 欧美激情操 | 超碰国产在线观看 | 欧美在线观看视频一区二区三区 | av亚洲产国偷v产偷v自拍小说 | 欧美午夜理伦三级在线观看 | 一个色综合网站 | 久久久久国产精品免费免费搜索 | 亚洲日本国产精品 | 欧美粗又大 | 97偷拍在线视频 | 国产高清av免费在线观看 | 久久精品99精品国产香蕉 | 天天天天天天天天操 | 亚洲精品视频免费在线 | 99精品偷拍视频一区二区三区 | 日本精品中文字幕在线观看 | 在线日韩一区 | 91九色最新 | www.国产在线观看 | 久久久99精品免费观看乱色 | 久青草国产在线 | 久久久www免费电影网 | 色视频在线观看免费 | 欧美精品免费一区二区 | 99视频免费观看 | 亚洲视频在线播放 | 午夜精品一区二区三区在线视频 | 天天干干| 色婷婷亚洲婷婷 | 国产精品免费在线观看视频 | 久草在线视频首页 | 国产免费国产 | 久久精品一二三 | 狠狠做深爱婷婷综合一区 | 日本三级在线观看中文字 | 精品福利在线视频 | 99精品视频精品精品视频 | 91色欧美| 狠狠躁日日躁狂躁夜夜躁av | 一区二区精品国产 | 99tvdz@gmail.com | 欧美小视频在线 | 欧美一区在线观看视频 | 亚洲 欧美 精品 | 国产一区自拍视频 | 欧美精品一二 | av网站免费线看精品 | 亚洲视频在线观看 | 日本一区二区三区免费观看 | 亚洲精品美女在线观看 | 亚洲精品乱码久久久久久蜜桃不爽 | 久久久久麻豆 | 中文字幕在线观看视频一区二区三区 | 日韩av手机在线观看 | 一二区精品 | 国产成人一区二区精品非洲 | 丁香婷婷在线观看 | 色天天综合久久久久综合片 | 欧美坐爱视频 | 日韩一级电影网站 | 99久久夜色精品国产亚洲96 | 999久久久欧美日韩黑人 | 四虎影视成人精品 | 色人久久 | 久久久久国产视频 | 日韩欧美aaa | 亚洲精品视频第一页 | 怡春院av | 午夜黄网 | 在线视频电影 | 国产 亚洲 欧美 在线 | 91福利在线导航 | 高清不卡免费视频 | 国产日产精品一区二区三区四区 | 久久久国产精品久久久 | 国产免费成人av | 欧美日韩国产免费视频 | 欧美在线视频一区二区 | 国产精品麻豆三级一区视频 | 国产成人av综合色 | 少妇性bbb搡bbb爽爽爽欧美 | 久久国产视频网站 | 2024av在线播放| 亚洲自拍av在线 | 观看免费av | 欧美日韩国产一区二区在线观看 | 最近中文字幕大全中文字幕免费 | 日本成人中文字幕在线观看 | 玖玖在线视频观看 | 精品三级av | 日韩1级片| 色九九视频 | 免费麻豆网站 | 国产人免费人成免费视频 | 亚洲精选久久 | 国产一级在线免费观看 | 免费在线观看a v | 亚洲国内精品视频 | 免费视频成人 | 精品一区二区精品 | 亚洲精品国产免费 | 国产1区在线观看 | 黄色片网站av | 欧美 日韩 视频 | 国产99久久久久 | 成人久久久电影 | 麻豆国产露脸在线观看 | 伊人视频 | 国产精品99久久久久久有的能看 | 日日干网 | 毛片99 | 日韩va欧美va亚洲va久久 | 蜜臀av性久久久久av蜜臀三区 | 久久网址| 91视频免费国产 | 国产中文在线视频 | 久草视频免费播放 | 日韩伦理片一区二区三区 | 亚洲国产精品500在线观看 | 很污的网站 | 精品国产一区二区三区久久影院 | 国产精品久久久久久久久久久久冷 | 91热爆在线观看 | 久久躁日日躁aaaaxxxx | 97综合在线| 欧美日韩在线观看一区 | 免费亚洲精品视频 | 亚洲国产高清视频 | 美女网站视频免费都是黄 | 日韩精品一区二区三区第95 | 9999在线| 婷婷色九月 | 黄色一级在线免费观看 | 96久久久| 中文字幕在线观看完整版电影 | 国产一区高清在线 | 久久av免费 | 日本韩国欧美在线观看 | 丰满少妇一级 | 国产在线观看免费观看 | 精品久久久免费视频 | 中文在线中文a | 国产在线日本 | 五月婷婷视频在线观看 | 午夜少妇一区二区三区 | 色在线国产 | 日韩成人免费观看 | 国产精品一区二区中文字幕 | 日韩电影精品 | 国产手机视频在线播放 | 国产一区在线看 | 黄色大片日本免费大片 | 在线观看视频一区二区三区 | 狠狠躁夜夜a产精品视频 | 天天综合天天做天天综合 | 91麻豆免费视频 | 久久国产精品久久久久 | 久久理论视频 | 国产精品嫩草影院123 | 中文欧美字幕免费 | 一区二区三区不卡在线 | 91精品国产综合久久久久久久 | 亚洲成人xxx | 深夜免费福利在线 | 国产精品久久久 | 国产91小视频 | 国产中文字幕网 | 久久精品艹 | ww视频在线观看 | 91视频91蝌蚪 | 伊人午夜| 91九色视频导航 | 视频在线99re | 亚洲九九九 | 在线黄av| 国产色女人 | www.久草.com | 天天艹天天干天天 | 麻豆94tv免费版 | 91视频a| 日韩av一区在线观看 | 久久精品欧美一 | 8090yy亚洲精品久久 | 国产高清无av久久 | 91精品视频观看 | 免费观看的黄色 | 日韩在线观看视频中文字幕 | 国产在线 一区二区三区 | 欧美成人影音 | 99久久久久成人国产免费 | 激情网在线视频 | 夜夜高潮夜夜爽国产伦精品 | 中文字幕在线观看播放 | 国产高清视频在线播放 | 91免费观看视频网站 | 超碰人人99 | 免费人做人爱www的视 | 18做爰免费视频网站 | 日本中文在线观看 | 91高清视频免费 | 国产三级国产精品国产专区50 | 午夜久久| 一级一片免费看 | 日本色小说视频 | 国产精品久久久久久一二三四五 | 亚州精品天堂中文字幕 | 国产人在线成免费视频 | 天天操天天爱天天爽 | 四虎在线免费 | 久久久精品国产免费观看一区二区 | 国产成人在线观看免费 | 国产精品美女 | 国产精品av免费在线观看 | 天天爱天天 | 久久精品亚洲精品国产欧美 | 99在线观看视频网站 | 日韩毛片在线免费观看 | 天天鲁天天干天天射 | 久草视频在线免费 | 久青草视频在线观看 | 白丝av在线 | 婷婷久久网站 | 精品久久美女 | 国产日韩精品一区二区在线观看播放 | 97人人爽 | 中文字幕一区二区三区在线观看 | av成人免费在线观看 | 摸阴视频 | 一本一本久久a久久精品综合小说 | 国产精品免费观看网站 | 色噜噜日韩精品一区二区三区视频 | 日韩av高潮| 日韩欧美国产精品 | 免费午夜视频在线观看 | 国产精品久久久久久久午夜 | 成年人免费在线播放 | 涩涩网站在线看 | 精品a级片| 在线免费高清 | 免费国产黄线在线观看视频 | 黄色影院在线免费观看 | 在线观看国产永久免费视频 | 日韩在线精品视频 | 国内视频在线 | 性色av免费在线观看 | 日本韩国欧美在线观看 | 一二三区高清 | 开心色激情网 | 精品视频www| 在线免费av观看 | 欧美极度另类性三渗透 | 成人免费在线播放 | 色婷婷综合在线 | 西西人体4444www高清视频 | 精品视频123区在线观看 | 国产精品18videosex性欧美 | 中文字幕乱码亚洲精品一区 | 视频高清 | 在线观看中文字幕dvd播放 | 九九免费精品视频 | 高清一区二区三区av | 久久精品国产亚洲精品 | 婷婷资源站 | 五月婷婷丁香网 | 91视频首页 | 久久精品久久精品久久精品 | 国内精品久久久久 | 黄色一级在线视频 | 人人涩 | 亚洲精品欧美精品 | 亚洲精品小区久久久久久 | 成人在线观看日韩 | 久久久国产一区二区三区 | 国产91综合一区在线观看 | 免费在线观看成年人视频 | 日日噜噜噜噜夜夜爽亚洲精品 | 狠狠干中文字幕 | 日韩久久久久久久久久 | 91免费视频黄 | 97碰碰视频 | 亚洲成av人片一区二区梦乃 | 国产亚洲视频在线观看 | 国产999精品久久久久久 | 婷婷综合影院 | 18久久久久久 | 久精品视频免费观看2 | 美女一二三区 | 欧美日韩在线观看一区 | 天天草夜夜 | 国内揄拍国内精品 | 91在线精品视频 | 国产在线精品国自产拍影院 | 午夜av网站 | 欧美日韩一区二区三区在线免费观看 | 成人午夜精品福利免费 | 99热这里只有精品国产首页 | 91在线91 | 久草在线视频精品 | 欧美日韩国产一区二区三区在线观看 | 91在线文字幕 | 999视频网站 | 日韩高清成人在线 | 在线免费观看黄色小说 | 久久人人爽人人爽人人 | 亚洲欧洲一级 | 97在线观看免费高清完整版在线观看 | 黄色免费高清视频 | 天干啦夜天干天干在线线 | 国产精品入口传媒 | 欧美a√在线 | 日韩精品视频在线观看免费 | 成人午夜在线观看 | 91麻豆精品91久久久久同性 | 国产精品6999成人免费视频 | 国产超碰在线 | 国产成人亚洲在线观看 | 欧美人体xx| 草樱av| 美女av免费 | 日韩网站免费观看 | 成人av一区二区三区 | 午夜视频不卡 | 久久最新| 黄色影院在线免费观看 | 国产玖玖在线 | 九九99靖品| 最新91在线视频 | 成人网在线免费视频 | 91成人久久| 天天操夜操视频 | 在线a亚洲视频播放在线观看 | 涩涩色亚洲一区 | 亚洲区另类春色综合小说校园片 | 麻豆国产在线视频 | 欧美性久久久久久 | 日本中文字幕一二区观 | 日韩久久久久久久 | 日日操夜夜操狠狠操 | 在线中文字幕播放 | 8x8x在线观看视频 | 久久99网站 | 五月天婷婷免费视频 | 久久精品中文字幕免费mv | 欧美成人免费在线 | 国产99精品 | 中文字幕字幕中文 | 久久大片 | 狠狠干婷婷 | 午夜av片| 久久久久久久久久久久久久av | 国产精品嫩草在线 | www.综合网.com | 欧美少妇bbwhd | 国产做aⅴ在线视频播放 | 婷婷午夜天 | 99久久精品国产一区二区三区 | 色综合五月 | 国产中文 | 日韩激情在线视频 | 亚洲成人黄色在线 | 亚洲高清视频在线 | 激情综合啪 | 久久久久免费精品国产小说色大师 | 999一区二区三区 | 人人草网站 | 精品国产伦一区二区三区观看说明 | 久久69精品久久久久久久电影好 | 亚洲三级黄色 | 免费在线播放视频 | 午夜电影久久 | 处女av在线 | 日韩特黄一级欧美毛片特黄 | 麻豆视频在线免费看 | 在线国产不卡 | 三上悠亚在线免费 | 白丝av在线 | 99免费在线观看视频 | 激情av资源网| 久久久99精品免费观看 | 国产成人精品免费在线观看 | 色网站视频 | 国产无吗一区二区三区在线欢 | 日批视频在线播放 | 成人黄色电影在线播放 | 中文字幕在线影视资源 | 97视频在线看 | 91九色在线视频观看 | 欧美在线不卡一区 | 国产精品v欧美精品v日韩 | 色婷婷免费视频 | 最新动作电影 | 国产精品网址在线观看 | 国产在线观看二区 | 国产日韩欧美在线观看视频 | 免费三级黄色 | 亚洲日日日 | 黄在线免费看 | 欧美午夜性生活 | 国产69精品久久久久久久久久 | 久久久影院一区二区三区 | 久久久在线观看 | 天天射日 | 日本精品视频一区二区 | 久草网站 | 欧美国产日韩在线观看 | 在线v| 日韩欧美在线一区二区 | 中文字幕中文字幕在线一区 | 亚洲国产理论片 | 免费视频三区 | 精品99久久| 亚洲女欲精品久久久久久久18 | 全黄色一级片 | 日本高清久久久 | 久久精品视频在线观看免费 | 中午字幕在线 | 碰超在线97人人 | 欧美性脚交| 色婷丁香 | 美女黄频| www.91成人| 8x8x在线观看视频 | 日本不卡一区二区三区在线观看 | 久久久久久久久久久国产精品 | 狠狠躁夜夜躁人人爽视频 | 欧美精品久久久 | 在线观看免费视频你懂的 | 国产精品久久视频 | 欧美日韩国产精品一区二区 | 国产成人精品久久 | 国产国产人免费人成免费视频 | 天天夜夜狠狠操 | 97在线观看视频国产 | 日p视频 | 中文在线字幕免费观看 | av大全在线| 国产中文自拍 | 91丨九色丨高潮丰满 | 四虎成人精品永久免费av | 丁香六月婷婷激情 | 亚洲成人精品在线 | 欧美少妇xxx | 亚洲成人免费在线 | 国产精品久久网 | 国产一级视屏 | 国产黄色免费 | 久久综合久久综合这里只有精品 | 伊人网综合在线观看 | 日日干夜夜爱 | 中文字幕免费看 | 久久99国产精品久久99 | 在线视频第一页 | 超碰97在线资源站 | 色在线高清| 亚洲精品综合久久 | 日韩在线视频免费看 | 国产成人精品免高潮在线观看 | 亚洲 成人 一区 | 成人片在线播放 | 久久理论视频 | 亚洲综合精品视频 | 福利电影一区二区 | 二区三区在线观看 | 97在线观看免费观看高清 | av黄色免费看 | 免费观看丰满少妇做爰 | 欧美午夜一区二区福利视频 | 精品国产一区二区三区四区在线观看 | 特级毛片在线 | www天天操 | 久久人人爽人人爽 | 久久国产精品99国产 | 欧美一区二区日韩一区二区 | 最新av观看 | 99在线国产| 国产成人精品在线观看 | 亚洲一区二区精品视频 | 国产中文字幕在线播放 | 精品亚洲va在线va天堂资源站 | 婷婷视频 | 国产96在线观看 | 久久精品看 | 精品在线一区二区 | 国产性天天综合网 | 国产精品一区二区久久 | 日韩精品视频在线免费观看 | 久艹视频在线观看 |