spring小结(2)

上一节主要说了bean注册流程,下面再补充介绍其中关键的流程

再解析有@Config主机类时,也会处理@import

spring小结(2)

 

@Configuration
@ComponentScan("com.lmq.BaseService")
@Import("实现ImportBeanDefinitionRegistrar接口的类") //也可以是normal类,importSelect
public class AppConfig {

...........

//实现ImportBeanDefinitionRegistrar接口的类可以帮beanfactory加入某个beandefinition,相当于往map中put一个

spring注册类方法:

    1,register()  //需要是一个类,无法参与生成bd

    2, scan()  //需要是一个类,或者注解,无法参与生成bd

    3,ImportBeanDefinitionRegistrar, 好处参与生成bd ,好比MapperScan把@mapper接口变成对象,

@Documented
@Import({MapperScannerRegistrar.class})
public @interface MapperScan {
    String[] value() default {};

其中MapperScannerRegistrar.class帮助注册一个bean,

class MapperScannerRegistrar implements ImportBeanDefinitionRegistrar, ResourceLoaderAware {
    private ResourceLoader resourceLoader;

    public MapperScannerRegistrar() {
    }

    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {。。。。//这里registry上节讲过是beanfactory

以上是例子,帮助理解ImportBeanDefinitionRegistrar

扯远了

进去此方法,

private void processImports(ConfigurationClass configClass, SourceClass currentSourceClass,
      Collection<SourceClass> importCandidates, boolean checkForCircularImports) {

   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();
               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 {
                  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 {//import 普通类
               // 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();
      }
   }
}