博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
spring源码解析bean定义@Configuration、@Import、@Bean(2)
阅读量:6613 次
发布时间:2019-06-24

本文共 15464 字,大约阅读时间需要 51 分钟。

hot3.png

前言

本文转自“天河聊技术”微信公众号

本次继续介绍@Configuration、@Import、 bean定义解析

 

正文

进入这个方法

org.springframework.context.annotation.ConfigurationClassParser#processImports

private void processImports(ConfigurationClass configClass, SourceClass currentSourceClass,         Collection
importCandidates, boolean checkForCircularImports) throws IOException { if (importCandidates.isEmpty()) { return;      } if (checkForCircularImports && isChainedImportOnStack(configClass)) { this.problemReporter.error(new CircularImportProblem(configClass, this.importStack));      } else { 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();//                初始化@Import处理器                  ImportSelector selector = BeanUtils.instantiateClass(candidateClass, ImportSelector.class);                  ParserStrategyUtils.invokeAwareMethods( selector, this.environment, this.resourceLoader, this.registry);                  if (this.deferredImportSelectors != null && selector instanceof DeferredImportSelector) { this.deferredImportSelectors.add( new DeferredImportSelectorHolder(configClass, (DeferredImportSelector) selector));                  } else {//                   解析@Configuration元注解信息选择要导入的类的信息                     String[] importClassNames = selector.selectImports(currentSourceClass.getMetadata());                     Collection
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);                  ParserStrategyUtils.invokeAwareMethods( registrar, this.environment, this.resourceLoader, this.registry);                  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 (Throwable ex) { throw new BeanDefinitionStoreException( "Failed to process import candidates for configuration class [" + configClass.getMetadata().getClassName() + "]", ex);         } finally { this.importStack.pop();         } } }

找到这行代码

//                    递归调用                     processImports(configClass, currentSourceClass, importSourceClasses, false);
      递归调用                  processConfigurationClass(candidate.asConfigClass(configClass));

找到这个方法org.springframework.context.annotation.ConfigurationClassParser#doProcessConfigurationClass这一行代码

// Process any @ImportResource annotations 解析@ImportResource的属性值AnnotationAttributes importResource =      AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class);
//        资源路径是数组的形式         String[] resources = importResource.getStringArray("locations");

找到这行代码

// Process individual @Bean methods 解析带有@Bean的方法源数据Set
beanMethods = retrieveBeanMethodMetadata(sourceClass);

进入这个方法

org.springframework.context.annotation.ConfigurationClassParser#retrieveBeanMethodMetadata

检索@Bean注解的方法源数据

private Set
retrieveBeanMethodMetadata(SourceClass sourceClass) { AnnotationMetadata original = sourceClass.getMetadata();//    从源数据中获取@Bean的方法源数据      Set
beanMethods = original.getAnnotatedMethods(Bean.class.getName());      if (beanMethods.size() > 1 && original instanceof StandardAnnotationMetadata) { // Try reading the class file via ASM for deterministic declaration order...         // Unfortunately, the JVM's standard reflection returns methods in arbitrary         // order, even between different runs of the same application on the same JVM.         try { AnnotationMetadata asm = this.metadataReaderFactory.getMetadataReader(original.getClassName()).getAnnotationMetadata();            Set
asmMethods = asm.getAnnotatedMethods(Bean.class.getName());            if (asmMethods.size() >= beanMethods.size()) { Set
selectedMethods = new LinkedHashSet<>(asmMethods.size());               for (MethodMetadata asmMethod : asmMethods) { for (MethodMetadata beanMethod : beanMethods) { if (beanMethod.getMethodName().equals(asmMethod.getMethodName())) { selectedMethods.add(beanMethod);                        break;                     } } } if (selectedMethods.size() == beanMethods.size()) { // All reflection-detected methods found in ASM method set -> proceed                  beanMethods = selectedMethods;               } } } catch (IOException ex) { logger.debug("Failed to read class file via ASM for determining @Bean method order", ex);            // No worries, let's continue with the reflection metadata we started with...         } } return beanMethods;   }

返回到这个方法

org.springframework.context.annotation.ConfigurationClassPostProcessor#processConfigBeanDefinitions这行代码

//        加载bean定义         this.reader.loadBeanDefinitions(configClasses);

进入这个方法

org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader#loadBeanDefinitionsForConfigurationClass

private void loadBeanDefinitionsForConfigurationClass(ConfigurationClass configClass,         TrackedConditionEvaluator trackedConditionEvaluator) {      if (trackedConditionEvaluator.shouldSkip(configClass)) {         String beanName = configClass.getBeanName();         if (StringUtils.hasLength(beanName) && this.registry.containsBeanDefinition(beanName)) {            this.registry.removeBeanDefinition(beanName);         }         this.importRegistry.removeImportingClass(configClass.getMetadata().getClassName());         return;      }      if (configClass.isImported()) {//       将@Configuration的类本身注册为bean定义         registerBeanDefinitionForImportedConfigurationClass(configClass);      }      for (BeanMethod beanMethod : configClass.getBeanMethods()) {//       根据bean的method加载bean定义         loadBeanDefinitionsForBeanMethod(beanMethod);      }      loadBeanDefinitionsFromImportedResources(configClass.getImportedResources());      loadBeanDefinitionsFromRegistrars(configClass.getImportBeanDefinitionRegistrars());   }

进入这个方法

//        将@Configuration的类本身注册为bean定义         registerBeanDefinitionForImportedConfigurationClass(configClass);
private void registerBeanDefinitionForImportedConfigurationClass(ConfigurationClass configClass) {      AnnotationMetadata metadata = configClass.getMetadata();      AnnotatedGenericBeanDefinition configBeanDef = new AnnotatedGenericBeanDefinition(metadata);//    解析scope的源数据      ScopeMetadata scopeMetadata = scopeMetadataResolver.resolveScopeMetadata(configBeanDef);      configBeanDef.setScope(scopeMetadata.getScopeName());//    生成beanName      String configBeanName = this.importBeanNameGenerator.generateBeanName(configBeanDef, this.registry);//    解析一般的bean定义属性      AnnotationConfigUtils.processCommonDefinitionAnnotations(configBeanDef, metadata);      BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(configBeanDef, configBeanName);      definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);//    bean定义注册      this.registry.registerBeanDefinition(definitionHolder.getBeanName(), definitionHolder.getBeanDefinition());      configClass.setBeanName(configBeanName);      if (logger.isDebugEnabled()) {         logger.debug("Registered bean definition for imported class '" + configBeanName + "'");      }   }

返回到org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader#loadBeanDefinitionsForConfigurationClass这个方法的这行代码

//        将@Configuration的类本身注册为bean定义         registerBeanDefinitionForImportedConfigurationClass(configClass);
private void registerBeanDefinitionForImportedConfigurationClass(ConfigurationClass configClass) {      AnnotationMetadata metadata = configClass.getMetadata();      AnnotatedGenericBeanDefinition configBeanDef = new AnnotatedGenericBeanDefinition(metadata);//    解析scope的源数据      ScopeMetadata scopeMetadata = scopeMetadataResolver.resolveScopeMetadata(configBeanDef);      configBeanDef.setScope(scopeMetadata.getScopeName());//    生成beanName      String configBeanName = this.importBeanNameGenerator.generateBeanName(configBeanDef, this.registry);//    解析一般的bean定义属性      AnnotationConfigUtils.processCommonDefinitionAnnotations(configBeanDef, metadata);      BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(configBeanDef, configBeanName);      definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);//    bean定义注册      this.registry.registerBeanDefinition(definitionHolder.getBeanName(), definitionHolder.getBeanDefinition());      configClass.setBeanName(configBeanName);      if (logger.isDebugEnabled()) {         logger.debug("Registered bean definition for imported class '" + configBeanName + "'");      }   }

返回到到这个方法org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader#loadBeanDefinitionsForConfigurationClass的这一行代码

for (BeanMethod beanMethod : configClass.getBeanMethods()) {//       根据bean的method加载bean定义         loadBeanDefinitionsForBeanMethod(beanMethod);      }

进入这个方法

org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader#loadBeanDefinitionsForBeanMethod

private void loadBeanDefinitionsForBeanMethod(BeanMethod beanMethod) {      ConfigurationClass configClass = beanMethod.getConfigurationClass();      MethodMetadata metadata = beanMethod.getMetadata();      String methodName = metadata.getMethodName();      // Do we need to mark the bean as skipped by its condition?      if (this.conditionEvaluator.shouldSkip(metadata, ConfigurationPhase.REGISTER_BEAN)) {         configClass.skippedBeanMethods.add(methodName);         return;      }      if (configClass.skippedBeanMethods.contains(methodName)) {         return;      }//    从源数据中获取@Bean的属性值      AnnotationAttributes bean = AnnotationConfigUtils.attributesFor(metadata, Bean.class);      Assert.state(bean != null, "No @Bean annotation attributes");      // Consider name and any aliases      List
names = new ArrayList<>(Arrays.asList(bean.getStringArray("name")));      String beanName = (!names.isEmpty() ? names.remove(0) : methodName);      // Register aliases even when overridden 注册别名      for (String alias : names) { this.registry.registerAlias(beanName, alias);      } // Has this effectively been overridden before (e.g. via XML)? 这是否已经被有效地覆盖了(例如通过XML)?      if (isOverriddenByExistingDefinition(beanMethod, beanName)) { if (beanName.equals(beanMethod.getConfigurationClass().getBeanName())) { throw new BeanDefinitionStoreException(beanMethod.getConfigurationClass().getResource().getDescription(),                  beanName, "Bean name derived from @Bean method '" + beanMethod.getMetadata().getMethodName() + "' clashes with bean name for containing configuration class; please make those names unique!");         } return;      } ConfigurationClassBeanDefinition beanDef = new ConfigurationClassBeanDefinition(configClass, metadata);      beanDef.setResource(configClass.getResource());      beanDef.setSource(this.sourceExtractor.extractSource(metadata, configClass.getResource()));      if (metadata.isStatic()) { // static @Bean method         beanDef.setBeanClassName(configClass.getMetadata().getClassName());         beanDef.setFactoryMethodName(methodName);      } else { // instance @Bean method         beanDef.setFactoryBeanName(configClass.getBeanName());         beanDef.setUniqueFactoryMethodName(methodName);      }//    设置自动装配模式为构造方法装配      beanDef.setAutowireMode(RootBeanDefinition.AUTOWIRE_CONSTRUCTOR);//    默认Required属性值是true      beanDef.setAttribute(RequiredAnnotationBeanPostProcessor.SKIP_REQUIRED_CHECK_ATTRIBUTE, Boolean.TRUE);//    解析一般的bean定义属性值      AnnotationConfigUtils.processCommonDefinitionAnnotations(beanDef, metadata);//    解析autowire属性      Autowire autowire = bean.getEnum("autowire");      if (autowire.isAutowire()) { beanDef.setAutowireMode(autowire.value());      }//    解析initMethod初始化方法      String initMethodName = bean.getString("initMethod");      if (StringUtils.hasText(initMethodName)) { beanDef.setInitMethodName(initMethodName);      }//    解析destroyMethod方法      String destroyMethodName = bean.getString("destroyMethod");      beanDef.setDestroyMethodName(destroyMethodName);      // Consider scoping 默认scope属性值是no      ScopedProxyMode proxyMode = ScopedProxyMode.NO;//    获取@Scope的值      AnnotationAttributes attributes = AnnotationConfigUtils.attributesFor(metadata, Scope.class);      if (attributes != null) { beanDef.setScope(attributes.getString("value"));         proxyMode = attributes.getEnum("proxyMode");         if (proxyMode == ScopedProxyMode.DEFAULT) { proxyMode = ScopedProxyMode.NO;         } } // Replace the original bean definition with the target one, if necessary 如果需要,将原始bean定义替换为目标函数。      BeanDefinition beanDefToRegister = beanDef;      if (proxyMode != ScopedProxyMode.NO) {//       cglib动态代理         BeanDefinitionHolder proxyDef = ScopedProxyCreator.createScopedProxy( new BeanDefinitionHolder(beanDef, beanName), this.registry,               proxyMode == ScopedProxyMode.TARGET_CLASS);         beanDefToRegister = new ConfigurationClassBeanDefinition( (RootBeanDefinition) proxyDef.getBeanDefinition(), configClass, metadata);      } if (logger.isDebugEnabled()) { logger.debug(String.format("Registering bean definition for @Bean method %s.%s()",               configClass.getMetadata().getClassName(), beanName));      }//    注册bean定义      this.registry.registerBeanDefinition(beanName, beanDefToRegister);   }

返回到这个方法org.springframework.context.support.AbstractApplicationContext#refresh

这一行代码

invokeBeanFactoryPostProcessors(beanFactory);

本次解析到这里结束。

 

 

最后

本次介绍到这里,以上内容仅供参考。

转载于:https://my.oschina.net/u/3775437/blog/1811538

你可能感兴趣的文章
UltraVNC
查看>>
详解synchronized
查看>>
Spring Cloud第二篇 创建一个Eureka Server
查看>>
初探数据双向绑定
查看>>
Webpack4 不深不浅的实践教程
查看>>
3分钟搞掂Set集合
查看>>
win10下安装Docker
查看>>
Linux下常用的磁盘管理技术LVM
查看>>
Silverlight杂记之HTTP通信WebClient介绍
查看>>
动态路由协议之RIP配置详解
查看>>
(apache+tomcat集群+memcached番外篇)单台tomcat的session信息的2种持久化方式
查看>>
nginx1.9+做TCP代理(端口转发)
查看>>
HTML元素的默认CSS设置介绍
查看>>
CSS-图片不变形设置
查看>>
Git异常:fatal: could not create work tree dir 'XXX': No such file or directory
查看>>
GNU make manual 翻译(八十二)
查看>>
python批量下载图片的三种方法
查看>>
[项目过程中所遇到的各种问题记录]部署篇——项目部署过程中那些纠结的问题-IIS...
查看>>
/bin/bash^M: bad interpreter: 没有那个文件或目录
查看>>
apiCloud手动检测更新
查看>>