spring源码解析bean定义@Configuration、@Import、@Bean(2)

前言

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

正文

进入这个方法

org.springframework.context.annotation.ConfigurationClassParser#processImports

private void processImports(ConfigurationClass configClass, SourceClass currentSourceClass,
         Collection<SourceClass> 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<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);
                  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<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass);

进入这个方法

org.springframework.context.annotation.ConfigurationClassParser#retrieveBeanMethodMetadata

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

private Set<MethodMetadata> retrieveBeanMethodMetadata(SourceClass sourceClass) {
      AnnotationMetadata original = sourceClass.getMetadata();
//    从源数据中获取@Bean的方法源数据
      Set<MethodMetadata> 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<MethodMetadata> asmMethods = asm.getAnnotatedMethods(Bean.class.getName());
            if (asmMethods.size() >= beanMethods.size()) {
               Set<MethodMetadata> 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<String> 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);

本次解析到这里结束。

最后

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

扫码关注

进群讨论

猜你喜欢

转载自my.oschina.net/u/3775437/blog/1811538