Spring 容器初始化 register 与 refresh方法

目录
  • register方法
  • refresh 方法
    • 1、prepareRefresh
    • 2、obtainFreshBeanFactory
    • 3、prepareBeanFactory
    • 4、postProcessBeanFactory
    • 5、invokeBeanFactoryPostProcessors
    • 6、registerBeanPostProcessors
    • 7、非重点部分

前篇回顾:

Spring源码解析容器初始化构造方法

在上一篇文章中,我们介绍完了AnnotationConfigApplicationContext的构造方法,本文我们来详细说说接下来要被调用的方法。

register方法

到上面位为止,AnnotationConfigApplicationContext构造函数执行完毕,调用register方法注册配置类,实际执行方法doRegisterBean

  <T> void doRegisterBean(Class<T> annotatedClass, @Nullable Supplier<T> instanceSupplier, @Nullable String name,
      @Nullable Class<? extends Annotation>[] qualifiers, BeanDefinitionCustomizer... definitionCustomizers) {
    AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);
    //判断这个类是否需要解析,主要根据注解进行判断
    if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
      return;
    }
    abd.setInstanceSupplier(instanceSupplier);
    //得到类的作用域
    ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
    //把类的作用域添加到数据结构中
    abd.setScope(scopeMetadata.getScopeName());
    //生成类的名字,通过beanNameGenerator
    String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
    AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);

    if (qualifiers != null) {
      for (Class<? extends Annotation> qualifier : qualifiers) {
        if (Primary.class == qualifier) {
          abd.setPrimary(true);
        }
        else if (Lazy.class == qualifier) {
          abd.setLazyInit(true);
        }
        else {
          abd.addQualifier(new AutowireCandidateQualifier(qualifier));
        }
      }
    }
    for (BeanDefinitionCustomizer customizer : definitionCustomizers) {
      customizer.customize(abd);
    }

    BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
    definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
    BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
  }

在上面这段代码中,主要完成这几项任务:

  • 首先根据我们传入的类创建一个AnnotatedGenericBeanDefinition,它可以理解为一个数据结构,其中包含了类的一些元信息,例如作用域scope,懒加载lazy等属性。
  • 调用processCommonDefinitionAnnotations方法,处理类中的通用注解,分析源码得知处理了Lazy,DependsOn,Primary,Role等注解,处理完成后把它们添加到数据结构中。
  • 封装成BeanDefinitionHolderBeanDefinitionHolder可以简单的理解为一个Map,它关联BeanDefinitionbeanName
  • 调用registerBeanDefinition方法,将上面的BeanDefinitionHolder注册给registry,这个registry就是 AnnotationConfigApplicationContext,即BeanDefinitionRegistry
  public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
      throws BeanDefinitionStoreException {
    this.beanFactory.registerBeanDefinition(beanName, beanDefinition);
  }

这里最终将beanDefinition注册给了之前实例化的beanFactorybeanFactory的实现类为DefaultListableBeanFactory

到这,我们已经有两种方法将一个类转化为BeanDefinition

1、通过RootBeanDefinition 的构造方法

2、调用AnnotatedBeanDefinitionReaderregister方法

执行完这一步后,可以看到我们的配置类也被放入了beanDefinitionMap,到这里,spring的工厂初始化工作就完成了。

refresh 方法

注册完成后,调用核心方法refresh初始化spring环境:

public void refresh() throws BeansException, IllegalStateException {
    synchronized (this.startupShutdownMonitor) {
      prepareRefresh();
      ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
      prepareBeanFactory(beanFactory);
      try {
        postProcessBeanFactory(beanFactory);
        invokeBeanFactoryPostProcessors(beanFactory);
        registerBeanPostProcessors(beanFactory);
        initMessageSource();
        initApplicationEventMulticaster();
        onRefresh();
        registerListeners();
        finishBeanFactoryInitialization(beanFactory);
        finishRefresh();
      }
  ...
}

首先可以看到,方法中的代码是被synchronized加锁的,这样做是为了防止一个线程在执行refresh时,其他线程执行spring容器的启动或销毁操作。下面,我们开始分析一下其中重要的方法,重要的注释会写在代码中。

1、prepareRefresh

prepareRefresh方法中为一些启动的准备工作,包括记录启动时间,是否激活标识位,初始化属性源配置等工作

protected void prepareRefresh() {
    // 记录启动时间
    this.startupDate = System.currentTimeMillis();
    // closed 属性设置为 false
    this.closed.set(false);
    //将 active 属性设置为 true
    //上面两个都是 AtomicBoolean类型
    this.active.set(true);

    if (logger.isInfoEnabled()) {
      logger.info("Refreshing " + this);
    }
    //注解模式下此方法为空
    initPropertySources();
    getEnvironment().validateRequiredProperties();
     ...
  }

2、obtainFreshBeanFactory

返回我们之前创建好的DefaultListableBeanFactory实例beanFactory,这里使用的是它的接口ConfigurableListableBeanFactory来进行接收。

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
    refreshBeanFactory();
    ConfigurableListableBeanFactory beanFactory = getBeanFactory();
    if (logger.isDebugEnabled()) {
      logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
    }
    return beanFactory;
  }

这里进行一下补充,如果是基于xml的配置,那么是在obtainFreshBeanFactory方法中初始化BeanFactory工厂的,并进行bean的加载与注册,这里不再赘述。

3、prepareBeanFactory

准备bean工厂,对功能进行填充,例如配置了一些标准特征,比如上下文的加载器ClassLoaderpostProcessor后置处理器。

  protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    beanFactory.setBeanClassLoader(getClassLoader());
    //bean表达式的解释器
    beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
    //bean对象与String类型的转换,例如<property ref="dao">
    beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
    //spring核心代码,添加一个后置管理器
    //能在bean中获得到各种的*Aware
    beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
    //添加了自动注入的忽略列表
    beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
    beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
    beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
    beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
    beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
    beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);

    // BeanFactory interface not registered as resolvable type in a plain factory.
    // MessageSource registered (and found for autowiring) as a bean.
    beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
    beanFactory.registerResolvableDependency(ResourceLoader.class, this);
    beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
    beanFactory.registerResolvableDependency(ApplicationContext.class, this);

    //添加一个用于ApplicationListener的bean从事件广播器中添加或删除的后置处理器
    beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

    if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
      beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
      beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
    }
    /*
    * 如果自定义的bean中没有名为“systemProperties”和“systemEnvironment”的Bean
    * 则注册两个bean,key为“systemProperties”和“systemEnvironment”,Value为Map
    * 这两个bean就是一些系统配置和系统环境信息
    * */
    if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
      beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
    }
    if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
      beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
    }
    if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
      beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
    }
  }

需要说明的是添加后置处理器addBeanPostProcessor方法,在beanFactory中维护了一个spring后置处理器的列表:

private final List<BeanPostProcessor> beanPostProcessors = new CopyOnWriteArrayList<>();

最终调用的是List的add方法,将后置处理器添加到列表的尾部:

this.beanPostProcessors.add(beanPostProcessor);

这里有必要简单的对BeanPostProcessor进行一下说明:

public interface BeanPostProcessor {
  @Nullable
  default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
    return bean;
  }
  @Nullable
  default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
    return bean;
  }
}

postProcessBeforeInitialization在类的初始化之前执行,postProcessAfterInitialization在类的初始化之后执行。也就是说spring通过暴露出BeanPostProcessor这个后置处理器,可以让我们去插手bean的初始化过程。

ApplicationContextAwareProcessor实现了这个接口,通过它spring向外暴露了上下文环境ApplicationContext,供我们调用。

4、postProcessBeanFactory

postProcessBeanFactory是一个空的方法,没有任何实现:

  /**
   * Modify the application context's internal bean factory after its standard
   * initialization. All bean definitions will have been loaded, but no beans
   * will have been instantiated yet. This allows for registering special
   * BeanPostProcessors etc in certain ApplicationContext implementations.
   * @param beanFactory the bean factory used by the application context
   */
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
}

看一下源码中的注释,可理解可以通过子类扩展当前类,添加一些BeanPostProcessor,在BeanDefinition被加载但bean还没有实例化前,执行这些特殊的后置管理器进行功能扩展。

5、invokeBeanFactoryPostProcessors

在该方法中,执行已被注册的BeanFactoryPostProcessorBeanFactoryPostProcessor也是spring提供的扩展点之一,它运行于spring容器加载了beanDefinition之后,但还未实例化bean之前执行。通过实现这个接口,可以在bean创建之前修改beanDefinition的属性,并且可以同时配置多个BeanFactoryProcessor,通过设置order属性来控制顺序。

@FunctionalInterface
public interface BeanFactoryPostProcessor {
  void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
}

再来看看invokeBeanFactoryPostProcessors方法:

protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
    PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
    if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
      beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
      beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
    }
  }

这个需要注意的是getBeanFactoryPostProcessors方法,这个方法是获取手动注册给spring添加的BeanFactoryPostProcessor,这个“手动注册”并不是说写好了以后添加一个@Component注解就可以了,因为如果加了注解还是spring自己去扫描得到的。

看一下getBeanFactoryPostProcessors方法,就可以知道是这里直接返回了一个List:

  public List<BeanFactoryPostProcessor> getBeanFactoryPostProcessors() {
    return this.beanFactoryPostProcessors;
  }

而通过 AnnotationConfigApplicationContextaddBeanFactoryPostProcessor方法进行添加,则直接添加进了这个list中:

public void addBeanFactoryPostProcessor(BeanFactoryPostProcessor postProcessor) {
    Assert.notNull(postProcessor, "BeanFactoryPostProcessor must not be null");
    this.beanFactoryPostProcessors.add(postProcessor);
  }

回到代码中,调用执行了PostProcessorRegistrationDelegateinvokeBeanFactoryPostProcessors 方法,这个方法用于执行所有注册的BeanFactoryPostProcessor。该方法中,创建一个List存放spring内部自己实现了BeanDefinitionRegistryPostProcessor接口的对象,并从beanFactory中获取这个type的bean的名称:

List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
String[] postProcessorNames =
          beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);

此处,我们可以得到一个对应的beanName

在获取到beanName后,通过bean工厂的getBean方法将其实例化,并添加到currentRegistryProcessors中,然后调用invokeBeanDefinitionRegistryPostProcessors方法,执行所有的BeanDefinitionRegistryPostProcessor

for (String ppName : postProcessorNames) {
  if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
    currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
    processedBeans.add(ppName);
  }
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
//合并list
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
//清除list
currentRegistryProcessors.clear();

看一下currentRegistryProcessors中的实例,这个对象非常重要,会在后面讲到:

回到上面的调用过程,我们知道这个Collection中现在只有一个对象,所以调用的是上面提到的 ConfigurationClassPostProcessor对象的 postProcessBeanDefinitionRegistry方法:

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

最终调用ConfigurationClassPostProcessorprocessConfigBeanDefinitions。先看方法的前半段:

public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
  //定义一个list,存放beanFactory中的beanDefinition
  List<BeanDefinitionHolder> configCandidates = new ArrayList<>();
  //获取容器中注册的所有beanDefinition的名字,目前有了7个
  String[] candidateNames = registry.getBeanDefinitionNames();
  for (String beanName : candidateNames) {
    BeanDefinition beanDef = registry.getBeanDefinition(beanName);
    if (ConfigurationClassUtils.isFullConfigurationClass(beanDef) ||
        ConfigurationClassUtils.isLiteConfigurationClass(beanDef)) {
      //如果BeanDefinition中的configurationClass的属性为full或者lite,则意味着已经处理过了,直接跳过
      if (logger.isDebugEnabled()) {
        logger.debug("Bean definition has already been processed as a configuration class: " + beanDef);
      }
    }
    //判断是否Configuration类,如果加了Configuration下面的这几个注解就不再判断了
    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;
  }

这里先读取了BeanFactory中存放的7个beanDefinition,然后去判断是否加了以下注解:

@Configuration
@ComponentScan
@Import
@ImportResource

如果是,则添加到configCandidates的List中,运行到这,可以看到在里面存了一个我们自定义的添加了@Configuration注解的类:

向下运行,首先实例化了一个ConfigurationClassParser,用于解析各个配置类:

ConfigurationClassParser parser = new ConfigurationClassParser(
        this.metadataReaderFactory, this.problemReporter, this.environment,
        this.resourceLoader, this.componentScanBeanNameGenerator, registry);

然后,实例化 2个Set,candidates 用于将之前加入的configCandidates进行去重,因为有可能有多个配置类重复了。alreadyParsed 用于判断是否处理过,避免重复。

Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);
Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size());

调用ConfigurationClassParserparse方法:

do {
     parser.parse(candidates);
     ...
}
while (!candidates.isEmpty());

parse方法调用链较长,这里只列出其调用过程和重要扫描过程:

ConfigurationClassParser
# parse(Set<BeanDefinitionHolder> configCandidates)
# parse(AnnotationMetadata metadata, String beanName)
# processConfigurationClas(ConfigurationClass configClass)
# doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass)

重点看一下doProcessConfigurationClass方法:

Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable(
      sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class);

得到注解类的注解信息,例如basePackage等,存放在AnnotationAttributes中。之后对set进行遍历:

for (AnnotationAttributes componentScan : componentScans) {
  //扫描普通类,会扫描出来所有加了@Component注解的类
  //并且把扫描出来的普通bean放到map当中
  Set<BeanDefinitionHolder> scannedBeanDefinitions =
      this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());
  //这一步完成后扫描出来了所有类
  //检查扫描出的类是否还有 @Configuration
  for (BeanDefinitionHolder holder : scannedBeanDefinitions) {
    BeanDefinition bdCand = holder.getBeanDefinition().getOriginatingBeanDefinition();
    if (bdCand == null) {
      bdCand = holder.getBeanDefinition();
    }
    if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) {
      parse(bdCand.getBeanClassName(), holder.getBeanName());
    }
  }
}

这里的关键还是parse方法,调用ComponentScanAnnotationParser 的parse方法,然后调用ClassPathBeanDefinitionScannerdoScan方法,实现扫描核心功能:

protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
  Assert.notEmpty(basePackages, "At least one base package must be specified");
  Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<>();
  for (String basePackage : basePackages) {
    //扫描basePackage路径下的java文件
    //并把它转成BeanDefinition类型
    Set<BeanDefinition> candidates = findCandidateComponents(basePackage);

    for (BeanDefinition candidate : candidates) {
      //解析scope属性
      ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);
      candidate.setScope(scopeMetadata.getScopeName());
      String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);

      //所有扫描出来的类 是 ScannedGenericBeanDefinition  ,符合AbstractBeanDefinition
      //先设置默认值
      if (candidate instanceof AbstractBeanDefinition) {
        //如果这个类是AbstractBeanDefinition的子类
        //则为他设置默认值,比如lazy,init ,destroy
        postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);
      }
      if (candidate instanceof AnnotatedBeanDefinition) {
        //检查并且处理常用的注解
        //这里的处理主要是指把常用注解的值设置到AnnotatedBeanDefinition当中
        //当前前提是这个类型必须是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);
        //加入到BeanDefinitionMap当中
        registerBeanDefinition(definitionHolder, this.registry);
      }
    }
  }
  return beanDefinitions;
}

到这,spring已经把所有加了@Component类注解的类扫描出来,并生成对应的beanDefinition,最后通过registerBeanDefinition方法,放入beanDefinitionMap中。

到这,我们执行完了ConfigurationClassPostProcessorinvokeBeanDefinitionRegistryPostProcessors方法。

回到PostProcessorRegistrationDelegateinvokeBeanFactoryPostProcessors方法中继续向下执行:

invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);

第二行语句用于执行我们自定义的beanFactoryPostProcessor,由于现在不存在,可以直接忽略,重点看第一条。

有的同学可能会问,刚才不是执行了一条差不多的语句吗,而且这个registryProcessors里面的东西也没有变,还是ConfigurationClassPostProcessor,那么为什么要执行两遍?看一下继承关系:

BeanDefinitionRegistryPostProcessorBeanFactoryPostProcessor进行了扩展,添加了自己的方法。所以第一次执行的是:

BeanDefinitionRegistryPostProcessor # postProcessBeanDefinitionRegistry

而第二次执行的方法是:

BeanFactoryPostProcessor # postProcessBeanFactory

这里调用了ConfigurationClassPostProcessorpostProcessBeanFactory方法:

public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    int factoryId = System.identityHashCode(beanFactory);
    if (this.factoriesPostProcessed.contains(factoryId)) {
      throw new IllegalStateException(
          "postProcessBeanFactory already called on this post-processor against " + beanFactory);
    }
    this.factoriesPostProcessed.add(factoryId);
    if (!this.registriesPostProcessed.contains(factoryId)) {
      // BeanDefinitionRegistryPostProcessor hook apparently not supported...
      // Simply call processConfigurationClasses lazily at this point then.
      processConfigBeanDefinitions((BeanDefinitionRegistry) beanFactory);
    }

    enhanceConfigurationClasses(beanFactory);
    beanFactory.addBeanPostProcessor(new ImportAwareBeanPostProcessor(beanFactory));
  }

主要用于给我们的@Configuration配置类产生cglib代理,并添加一个ImportAwareBeanPostProcessor后置处理器,这个后置处理器会在后面实例化bean的过程中用到。

6、registerBeanPostProcessors

这一步用于向spring环境中注册BeanPostProcessors后置处理器,前面说过,BeanPostProcessors的作用是在bean初始化的时候允许我们人工进行插手,当然这里只是进行一个注册的过程,并不会实际执行,具体的执行是bean在初始化的时候。

protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
  PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}

调用registerBeanPostProcessors方法:

String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

首先从BeanDefinitionMap中找出所有实现BeanPostProcessor接口的类,并添加了一个BeanPostProcessorCheckerbeanFactory中,主要用于记录信息。

然后,创建了4个List用于缓存不同类型的后置处理器:

//存放实现PriorityOrdered接口的BeanPostProcessor
List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
//存放Spring内部的BeanPostProcesso
List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
//存放注册实现Ordered接口的BeanPostProcessors
List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>();
//存放常规的BeanPostProcessors
List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>();

对4个List分别调用PostProcessorRegistrationDelegateregisterBeanPostProcessors方法:

private static void registerBeanPostProcessors(
      ConfigurableListableBeanFactory beanFactory, List<BeanPostProcessor> postProcessors) {
    for (BeanPostProcessor postProcessor : postProcessors) {
      beanFactory.addBeanPostProcessor(postProcessor);
    }
  }

遍历列表,调用AbstractBeanFactoryaddBeanPostProcessor方法,将后置处理器加到beanPostProcessors中:

 public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {
    Assert.notNull(beanPostProcessor, "BeanPostProcessor must not be null");
    // 如果beanPostProcessor已经存在则移除
    this.beanPostProcessors.remove(beanPostProcessor);
    // beanFactory是否已注册过InstantiationAwareBeanPostProcessors
    if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) {
      this.hasInstantiationAwareBeanPostProcessors = true;
    }
    //beanFactory是否已注册过DestructionAwareBeanPostProcessor
    if (beanPostProcessor instanceof DestructionAwareBeanPostProcessor) {
      this.hasDestructionAwareBeanPostProcessors = true;
    }
    //将beanPostProcessor添加到beanPostProcessors中
    this.beanPostProcessors.add(beanPostProcessor);
  }

在这个方法中,如果beanPostProcessor已经存在则移除,这样做可以起到重排序的作用,如果beanPostProcessor原先在前面,经过删除后再添加,则变到最后面。到这,将所有实现了BeanPostProcessor接口的类加载到 BeanFactory 中。

7、非重点部分

以下部分是非重点部分,不需要过分关注,因此省略,只做一个大体的注释说明:

//初始化上下文的 MessageSource源
initMessageSource();
//初始化应用事件广播器
initApplicationEventMulticaster();
//空方法,可用做子类扩展
onRefresh();
//在所有注册的bean中查找Listener bean,注册到消息广播器中
registerListeners();

到此这篇关于Spring 容器初始化 register 与 refresh方法的文章就介绍到这了,更多相关Spring register 与 refresh方法内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • spring容器启动实现初始化某个方法(init)

    spring容器启动 初始化某方法(init) 1.前言 很多时候,我们需要在项目启动的时候,就要完成某些方法的执行.今天整理了一个简单的方法,使用spring容器中bean的属性:init-method 2.代码 /* 初始化的类.这里不需要添加任何注解 */ public class InitData { @Autowired private UserService userService; /* 初始化方法 */ public void inits(){ System.out.printl

  • SpringBoot 如何添加容器启动的初始化逻辑的操作方法

    背景 传统 SpringMVC 项目中,我们可以定义容器初始化 Servlet ,然后在 web.xml 配置该 Servlet ,指定 load-on-startup 就可以在容器启动后,执行一些系统的初始化逻辑.比如设置全局资源文件路径.加载系统定时任务.数据初始化等. 技术转换到 SpringBoot 的时候,该在哪里添加应用初始化的代码呢? 如果初始化逻辑中,有一些普通类,需要通过 Spring 的 ApplicationContext 的 getBean 获取依赖属性,如何保证 Spr

  • 浅谈spring容器中bean的初始化

    当我们在spring容器中添加一个bean时,如果没有指明它的scope属性,则默认是singleton,也就是单例的. 例如先声明一个bean: public class People { private String name; private String sex; public String getName() { return name; } public void setName(String name) { this.name = name; } public String get

  • 一个简单的Spring容器初始化流程详解

    前言 首先我们初始化一个最简单的容器,用这个容器研究初始化的流程. 下面就是一个再简单不过的IoC容器了,该容器包含了一个名为beanA的bean,我们初始化容器后,取出该Bean,并调用方法. public class BeanA { private String testStr = "Test"; public BeanA(){ System.out.println("Running A"); } public void sayHello(){ System.o

  • 使用spring容器在初始化Bean时前和后的操作

    目录 spring容器初始化Bean操作 @PostConstruct和@PreDestroy注解 在XML中定义init-method和destory-method方法 Bean实现InitializingBean和DisposableBean接口 Spring bean 初始化顺序 1.概述 2.InitializingBean vs init-method 3.@PostConstruct 4.小结一下吧 spring容器初始化Bean操作 在某些情况下,Spring容器在初始化Bean的

  • 理解 MyBatis 是如何在 Spring 容器中初始化的

    MyBatis 初始化过程就是生成一些必须的对象放到 Spring 容器中.问题是这个过程到底生成了哪些对象?当遇到 MyBatis 初始化失败时,如何正确的找到分析问题的切入点?本文将针对这些问题进行介绍. 本文基于 MyBatis 3 和 Spring,假设读者已经知道如何使用 Maven 和 MyBatis,以及了解 Spring 的容器机制. 一.Mybatis 三件套 我们知道 MyBatis 的主要功能是由 SqlSessionFactory 和 Mapper 两者提供的,初始化 M

  • Spring源码解析容器初始化构造方法

    目录 前言 构造方法 前言 Spring框架被广泛应用于我们的日常工作中,但是很长时间以来我都是只会使用,不懂它的作用原理.通过最近一段时间的阅读源码,个人发现通过阅读源码,能够帮助我们了解Spring的设计理念,并且对Java编程中的一些设计模式更加熟悉,所以记录一下自己对Spring源码的理解. 在开始进行源码学习前,首先再回顾一下三种Spring编程风格: 基于Schema,即通过xml标签的配置方式 基于Annotation的注解技术,使用@Component等注解配置bean 基于Ja

  • Spring 容器初始化 register 与 refresh方法

    目录 register方法 refresh 方法 1.prepareRefresh 2.obtainFreshBeanFactory 3.prepareBeanFactory 4.postProcessBeanFactory 5.invokeBeanFactoryPostProcessors 6.registerBeanPostProcessors 7.非重点部分 前篇回顾: Spring源码解析容器初始化构造方法 在上一篇文章中,我们介绍完了AnnotationConfigApplicatio

  • spring容器初始化遇到的死锁问题解决

    前言 最近启动spring项目的时候遇到一个死锁问题,使用jstack获取线程堆栈的时候,可以看到2个线程出现了死锁: 解决过程: DefaultSingletonBeanRegistry.getSingleton()源码如下,可以看到这个方法需要对singletonObjects加锁 第二处xxx.subject.core.cache.DataLocalcacheInit.afterPropertiesSet源码如下: 可以看到:这个bean在初始化的时候,会开启线程,调用另外一个bean的i

  • Spring容器初始化及问题解决方案

    1.Spring bean组件 "默认为单例模式scope="singleton, 运行JavaApplication容器启动时自动创建对象 scope="prototype"为多例模式,请求条件下才创建对象 2beans组件 里面default-init-method初始化方法加载,范围比较大,当没有此方法时不会报错,default-destroy-method销毁方法,default-lazy-init="true/false" 对象延时实例

  • 利用注解配置Spring容器的方法

    本文介绍了利用注解配置Spring容器的方法,分享给大家,具体如下: @Configuration标注在类上,相当于将该类作为spring的xml的标签 @Configuration public class SpringConfiguration { public SpringConfiguration() { System.out.println("初始化Spring容器"); } } 主函数进行测试 public class Main { public static void m

  • 使用Spring初始化加载InitializingBean()方法

    目录 Spring初始化加载InitializingBean() 1.spring初始化bean有两种方式 2.相同点 3.不同点 4.InitializingBean接口定义的源码如下所示 5.由于代码在项目启动的时候会执行afterPropertiesSet()方法 6.这个方法将在所有的属性被初始化后调用 关于InitializingBean简单使用 这是一个Spring组件Filer 实现了afterPropertiesSet方法 debug启动项目 Spring初始化加载Initial

  • Spring Bean初始化及销毁多种实现方式

    这篇文章主要介绍了Spring Bean初始化及销毁多种实现方式,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 一.前言 日常开发过程有时需要在应用启动之后加载某些资源,或者在应用关闭之前释放资源.Spring 框架提供相关功能,围绕 Spring Bean 生命周期,可以在 Bean 创建过程初始化资源,以及销毁 Bean 过程释放资源.Spring 提供多种不同的方式初始化/销毁 Bean,如果同时使用这几种方式,Spring 如何处理这几

  • Spring框架初始化解析

    一.Spring能做什么? Spring的主要目的是使J2EE易用和促进好编程习惯. 倒置控制容器 Spring的设计核心是 org.springframework.beans 包, 为与JavaBeans一起工作而设计. 这个包一般不直接被用户使用, 但作为基础为更多的其他功能服务. 下一个较高层面的抽象是"Bean Factory". Spring bean factory 是一个普通的Factory,它使对象能够按名称获取,并且能管理对象之间的关系. Bean factories

随机推荐