SpringBoot源码之容器刷新 refreshContext 方法详解


highlight: androidstudio

上一篇我们聊了Springboot的run方法,今天我们聊下关于容器刷新(refresh)

本文很长,请各位同学要忍一下~~~

好了,废话不多说,直接开干 !!!

1.refresh 主方法 (重要)

``` java public void refresh() throws BeansException, IllegalStateException { //加锁 防止出现其他线程也来刷新容器 synchronized(this.startupShutdownMonitor) { // 1.1 上下文刷新前的一些准备工作。如记录容器的启动时间、标记“已启动”状态、处理配置文件中的占位符等 this.prepareRefresh(); /* 1.2 创建 BeanFactory(DefaultListableBeanFactory) 并设置序列化id, 其用来加载 Bean 定义、注册 Bean 等 */ ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory(); // 1.3 设置 BeanFactory 的类加载器,添加几个 BeanPostProcessor,手动注册几个特殊的 bean this.prepareBeanFactory(beanFactory);

try {
        /* 
        1.4
        允许在上下文 子类中对 beanFactory进行 (后置处理) 
       【这里需要知道 BeanFactoryPostProcessor 这个知识点,Bean 如果实现了此接口,
        那么在容器初始化以后,Spring 会负责调用里面的 postProcessBeanFactory 方法。】
        这里是提供给子类的扩展点,到这里的时候,所有的 Bean 都加载、注册完成了,但是都还没有初始化
        具体的子类可以在这步的时候添加一些特殊的 BeanFactoryPostProcessor 的实现类或做点什么事
        */
        this.postProcessBeanFactory(beanFactory);

        //1.5 Bean工厂的后置处理器,BeanFactoryPostProcessor(触发时机:bean定义 注册之后; bean实例化之前)  
        //简单来说就是调用 BeanFactoryPostProcessor 各个实现类的 postProcessBeanFactory(factory) 方法
        this.invokeBeanFactoryPostProcessors(beanFactory);

        // 1.6 注册 BeanPostProcessor 的实现类,注意看和 BeanFactoryPostProcessor 的区别
        // 此接口两个方法: postProcessBeforeInitialization 和 postProcessAfterInitialization
        // 两个方法分别在 Bean 初始化之前和初始化之后得到执行。注意,到这里 Bean 还没初始化
        this.registerBeanPostProcessors(beanFactory);

        //国际化相关 (略)
        this.initMessageSource();

        //1.7 初始化当前 ApplicationContext 的事件广播器 (略)
        this.initApplicationEventMulticaster();

        //1.8 具体的子类可以在这里初始化一些特殊的 Bean
        this.onRefresh();

        //1.9 注册事件监听器,监听器需要实现 ApplicationListener 接口  (略)
        this.registerListeners();

        //2.0 初始化所有的 singleton beans(lazy-init 的除外)(重要)
        this.finishBeanFactoryInitialization(beanFactory);

        // 发布 ApplicationContext 初始化完成事件
        this.finishRefresh();

    } catch (BeansException var9) {
        if (this.logger.isWarnEnabled()) {
            this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);
        }
        //销毁bean
        this.destroyBeans();
        //清除缓存
        this.cancelRefresh(var9);
        //抛出异常
        throw var9;
    } finally {
        //重置 Spring 中的常见内省缓存,因为我们可能不再需要单例 bean 的元数据......
        this.resetCommonCaches();
    }

}

} ```

2. 接下来 将把以上流程展开

1.1 prepareRefresh

  • 上下文刷新前的一些准备工作。如记录容器的启动时间、标记“已启动”状态、处理配置文件中的占位符等 ```java protected void prepareRefresh() { // 记录启动时间 this.startupDate = System.currentTimeMillis(); this.closed.set(false); // 标记状态 this.active.set(true); if (this.logger.isDebugEnabled()) { if (this.logger.isTraceEnabled()) { this.logger.trace("Refreshing " + this); } else { this.logger.debug("Refreshing " + this.getDisplayName()); } }

    this.initPropertySources(); //校验必须配置 this.getEnvironment().validateRequiredProperties(); if (this.earlyApplicationListeners == null) { this.earlyApplicationListeners = new LinkedHashSet(this.applicationListeners); } else { this.applicationListeners.clear(); this.applicationListeners.addAll(this.earlyApplicationListeners); }

    this.earlyApplicationEvents = new LinkedHashSet(); } ```

1.2 obtainFreshBeanFactory

  • 创建 BeanFactory(DefaultListableBeanFactory) 并设置序列化id,其用来加载 Bean 定义、注册 Bean 等

java protected ConfigurableListableBeanFactory obtainFreshBeanFactory() { // 关闭旧的 BeanFactory (如果有),创建新的 BeanFactory(DefaultListableBeanFactory) 并设置序列化id,其用来加载 Bean 定义、注册 Bean 等 this.refreshBeanFactory(); // getBeanFactory BeanFactory实际为 DefaultListableBeanFactory 。 return this.getBeanFactory(); }

SpringBoot源码之容器刷新 refreshContext 方法详解_第1张图片

SpringBoot源码之容器刷新 refreshContext 方法详解_第2张图片

这里我们附一张 DefaultListableBeanFactory 类图,关于他 可以自行谷歌一下

SpringBoot源码之容器刷新 refreshContext 方法详解_第3张图片

1.3 prepareBeanFactory

  • 设置 BeanFactory 的类加载器,添加几个 BeanPostProcessor,手动注册几个特殊的 bean (prepareBeanFactory)

```java protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) { //设置类加载器 beanFactory.setBeanClassLoader(this.getClassLoader()); //beanFactory的表达式语言处理器,Spring3增加了表达式语言的支持,
//默认可以使用#{bean.xxx}的形式来调用相关属性值 beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader())); //设置PropertyEditorRegistrar,通过PropertyEditor将xml解析出来的bean属性(字符串)和相应的java类型做转换 beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, this.getEnvironment()));

/*
   添加后置处理器ApplicationContextAwareProcessor,在Bean初始化后自动执行各Aware接口的set方法

   实现了 Aware 接口的 beans 在初始化的时候,这个 processor 将会回调,
   这个我们很常用,如我们会为了获取 ApplicationContext 而 implement ApplicationContextAware
   注意:它不仅仅回调 ApplicationContextAware,
   还会负责回调 EnvironmentAware、ResourceLoaderAware 等,看下源码就清楚了

*/
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));

//忽略依赖了这几个接口的bean
beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
/*
为特殊的几个 bean 赋值
包括BeanFactory、ResourceLoader、ApplicationEventPublisher、ApplicationContext
*/
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);

//在 bean 实例化后,如果是 ApplicationListener 的子类,
//那么将其添加到 listener 列表中,可以理解成:注册 事件监听器
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

//如果存在loadTimeWeaver这个Bean,则增加对应的后置处理器
if (beanFactory.containsBean("loadTimeWeaver")) {
    beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
    beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}

//添加默认的系统环境bean  (如果没有的话)
if (!beanFactory.containsLocalBean("environment")) {
    beanFactory.registerSingleton("environment", this.getEnvironment());
}

if (!beanFactory.containsLocalBean("systemProperties")) {
    beanFactory.registerSingleton("systemProperties", this.getEnvironment().getSystemProperties());
}

if (!beanFactory.containsLocalBean("systemEnvironment")) {
    beanFactory.registerSingleton("systemEnvironment", this.getEnvironment().getSystemEnvironment());
}

} ```

1.4 postProcessBeanFactory (后置处理器)

java //空方法 专门为子类提供用于扩展 ,此时所有的 Bean 都加载、注册完成了,但是都还没有初始化, //这一步可以修改 bean 定义或者增加自定义的 bean。 protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) { }

此时所有的 Bean 都加载、注册完成了,但是都还没有初始化

1.5 invokeBeanFactoryPostProcessors (重要)

  • 该方法作用: 调用 BeanFactoryPostProcessor 各个实现类的 postProcessBeanFactory(factory) 方法
  • 如何扩展? : (可以实现 BeanDefinitionRegistryPostProcessor接口 和 BeanFactoryPostProcessor接口 来扩展)

```java protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) { //开始执行beanFactoryPostProcessor对应实现类,需要知道的是beanFactoryPostProcessor是spring的扩展接口,在刷新容器之前,该接口可以用来修改bean元数据信息 PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, this.getBeanFactoryPostProcessors()); if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean("loadTimeWeaver")) { beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory)); beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader())); }

} ```

紧接着我们看看 invokeBeanFactoryPostProcessors 做了什么

```java public static void invokeBeanFactoryPostProcessors( ConfigurableListableBeanFactory beanFactory, List beanFactoryPostProcessors) {

Set processedBeans = new HashSet<>();

//可以看到 这个方法是先处理 BeanDefinitionRegistryPostProcessor的实现, //然后再处理BeanFactoryPostProcessor的实现, //这也是为什么我们定义的扩展点 BeanDefinitionRegistryPostProcessorPoint先打印, //BeanFactoryPostProcessorPoint后打印的原因 if (beanFactory instanceof BeanDefinitionRegistry) { BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory; List regularPostProcessors = new ArrayList<>(); List registryProcessors = new ArrayList<>(); //开始遍历三个内部类,如果属于BeanDefinitionRegistryPostProcessor子类,加入到bean注册的集合,否则加入到regularPostProcessors for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) { if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) { BeanDefinitionRegistryPostProcessor registryProcessor = (BeanDefinitionRegistryPostProcessor) postProcessor; registryProcessor.postProcessBeanDefinitionRegistry(registry); registryProcessors.add(registryProcessor); } else { regularPostProcessors.add(postProcessor); } }

List currentRegistryProcessors = new ArrayList<>();

  //通过BeanDefinitionRegistryPostProcessor获取到对应的处理类“org.springframework.context.annotation.internalConfigurationAnnotationProcessor”,但是需要注意的是这个类在springboot中搜索不到,这个类的完全限定名在AnnotationConfigEmbeddedWebApplicationContext中,在进行初始化的时候会装配几个类,在创建AnnotatedBeanDefinitionReader对象的时候会将该类注册到bean对象中,此处可以看到internalConfigurationAnnotationProcessor为bean名称,容器中真正的类是ConfigurationClassPostProcessor
  String[] postProcessorNames =
        beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
  //首先执行类型为PriorityOrdered的BeanDefinitionRegistryPostProcessor
  //PriorityOrdered类型表明为优先执行
  for (String ppName : postProcessorNames) {
     if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
        //获取对应的bean
        currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
        //用来存储已经执行过的BeanDefinitionRegistryPostProcessor
        processedBeans.add(ppName);
     }
  }
  sortPostProcessors(currentRegistryProcessors, beanFactory);
  registryProcessors.addAll(currentRegistryProcessors);
  //开始执行装配逻辑
  invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
  currentRegistryProcessors.clear();

  //其次执行类型为Ordered的BeanDefinitionRegistryPostProcessor
  //Ordered表明按顺序执行
  postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
  for (String ppName : postProcessorNames) {
     if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
        currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
        processedBeans.add(ppName);
     }
  }
  sortPostProcessors(currentRegistryProcessors, beanFactory);
  registryProcessors.addAll(currentRegistryProcessors);
  invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
  currentRegistryProcessors.clear();

  //循环中执行类型不为PriorityOrdered,Ordered类型的BeanDefinitionRegistryPostProcessor
  boolean reiterate = true;
  while (reiterate) {
     reiterate = false;
     postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
     for (String ppName : postProcessorNames) {
        if (!processedBeans.contains(ppName)) {
           currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
           processedBeans.add(ppName);
           reiterate = true;
        }
     }
     sortPostProcessors(currentRegistryProcessors, beanFactory);
     registryProcessors.addAll(currentRegistryProcessors);
     invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
     currentRegistryProcessors.clear();
  }

  //执行父类方法,优先执行注册处理类 
  invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
  //执行有规则处理类
  invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);

} else { invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory); }

String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

List priorityOrderedPostProcessors = new ArrayList<>(); List orderedPostProcessorNames = new ArrayList<>(); List nonOrderedPostProcessorNames = new ArrayList<>(); for (String ppName : postProcessorNames) { if (processedBeans.contains(ppName)) { } else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) { priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class)); } else if (beanFactory.isTypeMatch(ppName, Ordered.class)) { orderedPostProcessorNames.add(ppName); } else { nonOrderedPostProcessorNames.add(ppName); } }

sortPostProcessors(priorityOrderedPostProcessors, beanFactory); invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

List orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size()); for (String postProcessorName : orderedPostProcessorNames) { orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class)); } sortPostProcessors(orderedPostProcessors, beanFactory); invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

List nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size()); for (String postProcessorName : nonOrderedPostProcessorNames) { nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class)); } invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);

beanFactory.clearMetadataCache(); } ```

方法有点长。。该方法中的方法不再展开,具体看上边代码中的注释即可。

另外: 我在项目中定义了多个扩展点 在这里应该是会加载 BeanFactoryPostProcessorPoint , BeanDefinitionRegistryPostProcessorPoint这俩扩展点的,下面我们截图看下。
关于扩展点的代码 在我的github项目中: https://github.com/598572/xzll

SpringBoot源码之容器刷新 refreshContext 方法详解_第4张图片

走到方法最后 我们来看看我们自定义的扩展点哈,从下图可以看到 我们自定义的两个扩展点 都被Spring管理起来了

我们看下执行完 invokeBeanFactoryPostProcessors (我们自定义的扩展点)的输出哈

Spring的扩展点我个人认为是个很重要的东西,熟练使用这些特性,将会给你带来很大的遍历(项目中也经常会有这样的场景)

invokeBeanFactoryPostProcessors 方法小结 :

  • 1. 回调符合要求的BeanDefinitionRegistryPostProcessor实现并向容器内添加bean类型等定义。
  • 2. 回调符合要求的BeanFactoryPostProcessor实现并向容器内bean做定义、添加属性等操作。

1.6 registerBeanPostProcessors

  • 该方法作用: 将bean后置处理器(BeanPostProcessor)排序然后注册到容器中。
  • 如何扩展? : 实现 BeanPostProcessor接口

```java

public static void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) { String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false); int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length; beanFactory.addBeanPostProcessor(new PostProcessorRegistrationDelegate.BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount)); List priorityOrderedPostProcessors = new ArrayList(); List internalPostProcessors = new ArrayList(); List orderedPostProcessorNames = new ArrayList(); List nonOrderedPostProcessorNames = new ArrayList(); String[] var8 = postProcessorNames; int var9 = postProcessorNames.length;

String ppName;
BeanPostProcessor pp;
for(int var10 = 0; var10 < var9; ++var10) {
    ppName = var8[var10];
    if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
        pp = (BeanPostProcessor)beanFactory.getBean(ppName, BeanPostProcessor.class);
        priorityOrderedPostProcessors.add(pp);
        if (pp instanceof MergedBeanDefinitionPostProcessor) {
            internalPostProcessors.add(pp);
        }
    } else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
        orderedPostProcessorNames.add(ppName);
    } else {
        nonOrderedPostProcessorNames.add(ppName);
    }
}

sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, (List)priorityOrderedPostProcessors);
List orderedPostProcessors = new ArrayList();
Iterator var14 = orderedPostProcessorNames.iterator();

while(var14.hasNext()) {
    String ppName = (String)var14.next();
    BeanPostProcessor pp = (BeanPostProcessor)beanFactory.getBean(ppName, BeanPostProcessor.class);
    orderedPostProcessors.add(pp);
    if (pp instanceof MergedBeanDefinitionPostProcessor) {
        internalPostProcessors.add(pp);
    }
}

sortPostProcessors(orderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, (List)orderedPostProcessors);
List nonOrderedPostProcessors = new ArrayList();
Iterator var17 = nonOrderedPostProcessorNames.iterator();

while(var17.hasNext()) {
    ppName = (String)var17.next();
    pp = (BeanPostProcessor)beanFactory.getBean(ppName, BeanPostProcessor.class);
    nonOrderedPostProcessors.add(pp);
    if (pp instanceof MergedBeanDefinitionPostProcessor) {
        internalPostProcessors.add(pp);
    }
}

registerBeanPostProcessors(beanFactory, (List)nonOrderedPostProcessors);
sortPostProcessors(internalPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, (List)internalPostProcessors);
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));

} ```

  • 上面的代码大致就是根据不同实现接口,排序、分批注册bean后置处理器其实和invokeBeanFactoryPostProcessors差不多 只不过 invokeBeanFactoryPostProcessors是针对 实现了BeanFactoryPostProcessors接口的类,而registerBeanPostProcessors是针对 实现了BeanPostProcessor接口的类

  • 所以我们可以根据需要在这两处扩展一下,比如设置、添加,修改bean的属性,对bean进行校验等,比如我们实际案例中,有个场景是对配置类 a (标有@ConfigurationProperties)的配置类,来进行属性校验。

如下是我定义的扩展点 BeanPostProcessPoint 演示

SpringBoot源码之容器刷新 refreshContext 方法详解_第5张图片

1.7 initApplicationEventMulticaster

  • 通过源码可以看出该方法实现逻辑与 initMessageSource 基本相同,其步骤如下:查找是否有 name 为 applicationEventMulticaster 的 bean,如果有则放到容器里,如果没有,初始化一个系统默认的 SimpleApplicationEventMulticaster 对象放入容器。

    1.8 onRefresh

  • 模板方法,可用于 refresh 动作的扩展,默认为空实现。在 SpringBoot 中主要用于启动内嵌的 Web 服务器toomcat。

1.9 registerListeners

注册监听器,找出系统中的 ApplicationListener 对象,注册到时间广播器中。如果有需要提前进行广播的事件,则执行广播

我们来总结一下,到目前为止,应该说 BeanFactory 已经创建完成,并且所有的实现了 BeanFactoryPostProcessor以及BeanPostProcessor 接口的类 的 postProcessBeanFactory(factory)、postProcessAfterInitialization 方法已经得到回调执行了。而且 Spring 已经“手动”注册了一些特殊的 Bean,如 environmentsystemProperties 等。

2.0 finishBeanFactoryInitialization (及其 非常 超级 ~~~重要)

  • 作用: 实例化,初始化bean ,循环依赖问题,以及对外暴露扩展点等等
  • 特点: 长,逻辑比较多,这里推荐一篇写的很详细的文章 https://javadoop.com/post/spring-ioc 我个人觉得写的很好。

  • 如果只是实例化bean,肯定很简单,其实就是jdk原生的反射机制,而spring实例化bean的代码之所以让人觉得很难消化,根本原因在于中间的"干扰钩子"太多,几乎在bean实例化的每一个阶段(分得很细),都"嵌入"了一些回调机制,这就导致看源码的时候干扰非常多。虽说有些回调机制干扰比较大,但是这些回调却又缺一不可,因为有了这些回调机制,用户就可以自定义代码"入侵"到实例化的任意阶段(实现对应接口+覆写方法),如果习惯了这种设计模式,相信看源码会顺畅很多,自己写代码的时候也可以考虑使用这种回调机制,暴露"入侵"接口。

  • 需要说明的是 在这一步 有很多的扩展点可用 关于扩展点的东西,见我的下一篇文章

剩下的就是初始化 singleton beans 了,我们知道它们是单例的,如果没有设置懒加载,那么 Spring 会在接下来初始化所有的 singleton beans。

```java // 判断有无ConversionService(bean属性类型转换服务接口),并初始化 protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) { if (beanFactory.containsBean("conversionService") && beanFactory.isTypeMatch("conversionService", ConversionService.class)) { beanFactory.setConversionService((ConversionService)beanFactory.getBean("conversionService", ConversionService.class)); }

// 如果beanFactory中不包含EmbeddedValueResolver,则向其中添加一个EmbeddedValueResolver
// EmbeddedValueResolver作用; 解析bean中的占位符和表达式
if (!beanFactory.hasEmbeddedValueResolver()) {
    beanFactory.addEmbeddedValueResolver((strVal) -> {
        return this.getEnvironment().resolvePlaceholders(strVal);
    });
}
// 初始化LoadTimeWeaverAware类型的bean 
// LoadTimeWeaverAware: 加载Spring Bean时织入第三方模块,如AspectJ
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
String[] var3 = weaverAwareNames;
int var4 = weaverAwareNames.length;

for(int var5 = 0; var5 < var4; ++var5) {
    String weaverAwareName = var3[var5];
    this.getBean(weaverAwareName);
}
// 释放临时类加载器
beanFactory.setTempClassLoader((ClassLoader)null);
//没什么别的目的,因为到这一步的时候,Spring 已经开始预初始化 singleton beans 了,
//肯定不希望这个时候还出现 bean 定义解析、加载、注册
beanFactory.freezeConfiguration();
// 初始化其他的非延迟加载的单例bean(重要重要重要~ 重要的事情说三遍 嘿嘿 )
beanFactory.preInstantiateSingletons();

} ```

preInstantiateSingletons

先说明一下

实例化 BeanFactory 中已经被注册但是未实例化的所有实例(懒加载的不需要实例化),主要操作是 BeanFactory 的 preInstantiateSingletons 方法。该方法分为两部分:

  1. 遍历已经解析出来的所有 beanDefinitionNames,如果该 BeanDefinition 不是抽象类、是单例且没有设置懒加载,则进行实例化和初始化。
  2. 遍历解析出来的 beanDefinitionNames,如果获得的单例是 SmartInitializingSingleton 的实现类,则会执行 afterSingletonsInstantiated 方法。注意该方法调用只会发生在启动阶段,后续懒加载对象再初始化的时候,不会再进行回调。

接下来我们看下这个方法哈

```java public void preInstantiateSingletons() throws BeansException { if (this.logger.isTraceEnabled()) { this.logger.trace("Pre-instantiating singletons in " + this); } //获取所有需要初始化的beanName 从 beanDefinitionNames集合中 List beanNames = new ArrayList(this.beanDefinitionNames); Iterator var2 = beanNames.iterator();

//下面这个循环,触发所有的非懒加载的 singleton beans 的初始化操作
while(true) {
    String beanName;
    Object bean;
    do {
        while(true) {
            RootBeanDefinition bd;
            do {
                do {
                    do {
                        if (!var2.hasNext()) {
                            var2 = beanNames.iterator();

                            while(var2.hasNext()) {
                                beanName = (String)var2.next();
                                Object singletonInstance = this.getSingleton(beanName);
                                // bean初始化后的回调方法。跟前面讲到的postProcessBeanDefinitionRegistry原理相似。
                                // 用户可实现SmartInitializingSingleton接口+覆写afterSingletonsInstantiated方法达到自定义回调逻辑(在我的项目中也这么测试了)
                                if (singletonInstance instanceof SmartInitializingSingleton) {
                                    SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton)singletonInstance;
                                    if (System.getSecurityManager() != null) {
                                        AccessController.doPrivileged(() -> {
                                            smartSingleton.afterSingletonsInstantiated();
                                            return null;
                                        }, this.getAccessControlContext());
                                    } else {
                                        smartSingleton.afterSingletonsInstantiated();
                                    }
                                }
                            }

                            return;
                        }

                        beanName = (String)var2.next();
                        bd = this.getMergedLocalBeanDefinition(beanName);
                    } while(bd.isAbstract());
                } while(!bd.isSingleton());
            } while(bd.isLazyInit());
            //处理FactoryBean给其加上前缀 &
            if (this.isFactoryBean(beanName)) {
                bean = this.getBean("&" + beanName);
                break;
            }

            this.getBean(beanName);
        }
    } while(!(bean instanceof FactoryBean));

    FactoryBean factory = (FactoryBean)bean;
    boolean isEagerInit;
    if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
        SmartFactoryBean var10000 = (SmartFactoryBean)factory;
        ((SmartFactoryBean)factory).getClass();
        isEagerInit = (Boolean)AccessController.doPrivileged(var10000::isEagerInit, this.getAccessControlContext());
    } else {
        isEagerInit = factory instanceof SmartFactoryBean && ((SmartFactoryBean)factory).isEagerInit();
    }

    if (isEagerInit) {
        this.getBean(beanName);
    }
}

} ``` 哇咔咔~~~ 一顿操作猛如虎??? 一个个while do看的我懵逼三连???哈哈

我们这里主要看下getBean方法做了什么?

  • 这个方法我们经常用来从 BeanFactory 中获取一个 Bean,而初始化的过程也封装到了这个方法里。

如下示例:我们自己写的service类(其实所有的非抽象 非懒加载的bean)都会在这里实例化 (先get没有的话才实例化哈)

SpringBoot源码之容器刷新 refreshContext 方法详解_第6张图片

  • 紧接着我们看下代码 ```java protected T doGetBean(String name, @Nullable Class requiredType, @Nullable Object[] args, boolean typeCheckOnly) throws BeansException { //这里应该是别名的转换 String beanName = this.transformedBeanName(name); Object sharedInstance = this.getSingleton(beanName); Object bean; //如果从map总没获取到 并且args是空的话 那么 请看 getObjectForBeanInstance注释 if (sharedInstance != null && args == null) { if (this.logger.isTraceEnabled()) { if (this.isSingletonCurrentlyInCreation(beanName)) { this.logger.trace("Returning eagerly cached instance of singleton bean '" + beanName + "' that is not fully initialized yet - a consequence of a circular reference"); } else { this.logger.trace("Returning cached instance of singleton bean '" + beanName + "'"); } } // 下面这个方法:如果是普通 Bean 的话,直接返回 sharedInstance, // 如果是 FactoryBean 的话,返回它创建后那个实例对象 bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, (RootBeanDefinition)null); } else { // 创建过了此 beanName 的 prototype 类型的 bean,那么抛异常, // 往往是因为陷入了循环引用 if (this.isPrototypeCurrentlyInCreation(beanName)) { throw new BeanCurrentlyInCreationException(beanName); } // 检查一下这个 BeanDefinition 在容器中是否存在 BeanFactory parentBeanFactory = this.getParentBeanFactory(); if (parentBeanFactory != null && !this.containsBeanDefinition(beanName)) { String nameToLookup = this.originalBeanName(name); if (parentBeanFactory instanceof AbstractBeanFactory) { return ((AbstractBeanFactory)parentBeanFactory).doGetBean(nameToLookup, requiredType, args, typeCheckOnly); }

    if (args != null) {
            return parentBeanFactory.getBean(nameToLookup, args);
        }
    
        if (requiredType != null) {
            return parentBeanFactory.getBean(nameToLookup, requiredType);
        }
    
        return parentBeanFactory.getBean(nameToLookup);
    }
    
    if (!typeCheckOnly) {
        this.markBeanAsCreated(beanName);
    }

    /* 稍稍总结一下: 到这里的话,要准备创建 Bean 了,对于 singleton 的 Bean 来说,容器中还没创建过此 Bean; 对于 prototype 的 Bean 来说,本来就是要创建一个新的 Bean。 */ try { RootBeanDefinition mbd = this.getMergedLocalBeanDefinition(beanName); this.checkMergedBeanDefinition(mbd, beanName, args); String[] dependsOn = mbd.getDependsOn(); String[] var11;

    // 先初始化依赖的所有 Bean,这个很好理解。
        // 注意,这里的依赖指的是 depends-on 中定义的依赖
        if (dependsOn != null) {
            var11 = dependsOn;
            int var12 = dependsOn.length;
    
            for(int var13 = 0; var13 < var12; ++var13) {
                String dep = var11[var13];
                // 检查是不是有循环依赖,这里的循环依赖和我们前面说的循环依赖又不一样,
                //这里肯定是不允许出现的,不然要乱套了.哈哈 肯定不能声明 a dependsOn b ,b dependsOn a,对吧?
                if (this.isDependent(beanName, dep)) {
                    throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
                }
                //注册依赖关系 参数一: 被依赖项,参数二: beanName
                this.registerDependentBean(dep, beanName);
    
                try {
                //获取依赖的bean
                    this.getBean(dep);
                } catch (NoSuchBeanDefinitionException var24) {
                    throw new BeanCreationException(mbd.getResourceDescription(), beanName, "'" + beanName + "' depends on missing bean '" + dep + "'", var24);
                }
            }
        }
        //如果是单列的话 创建bean 
        if (mbd.isSingleton()) {
            sharedInstance = this.getSingleton(beanName, () -> {
                try {
                    //******* 创建bean ******
                    return this.createBean(beanName, mbd, args);
                } catch (BeansException var5) {
                    this.destroySingleton(beanName);
                    throw var5;
                }
            });
            bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
        } else if (mbd.isPrototype()) {
            //多例的话 走这个if 
            var11 = null;
    
            Object prototypeInstance;
            try {
                this.beforePrototypeCreation(beanName);
                prototypeInstance = this.createBean(beanName, mbd, args);
            } finally {
                this.afterPrototypeCreation(beanName);
            }
    
            bean = this.getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
        } else {
            String scopeName = mbd.getScope();
            Scope scope = (Scope)this.scopes.get(scopeName);
            if (scope == null) {
                throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
            }
    
            try {
                Object scopedInstance = scope.get(beanName, () -> {
                    this.beforePrototypeCreation(beanName);
    
                    Object var4;
                    try {
                        var4 = this.createBean(beanName, mbd, args);
                    } finally {
                        this.afterPrototypeCreation(beanName);
                    }
    
                    return var4;
                });
                bean = this.getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
            } catch (IllegalStateException var23) {
                throw new BeanCreationException(beanName, "Scope '" + scopeName + "' is not active for the current thread; consider defining a scoped proxy for this bean if you intend to refer to it from a singleton", var23);
            }
        }
    } catch (BeansException var26) {
        this.cleanupAfterBeanCreationFailure(beanName);
        throw var26;
    }

    } // 最后,检查一下类型对不对,不对的话就抛异常,对的话就返回了 if (requiredType != null && !requiredType.isInstance(bean)) { try { T convertedBean = this.getTypeConverter().convertIfNecessary(bean, requiredType); if (convertedBean == null) { throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass()); } else { return convertedBean; } } catch (TypeMismatchException var25) { if (this.logger.isTraceEnabled()) { this.logger.trace("Failed to convert bean '" + name + "' to required type '" + ClassUtils.getQualifiedName(requiredType) + "'", var25); }

    throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
    }

    } else { return bean; } } ```

  • 我们看下创建bean之前的一些参数 beanName, mbd,args都是什么 见下图:

SpringBoot源码之容器刷新 refreshContext 方法详解_第7张图片

  • 接着 我们看下 return this.createBean(beanName, mbd, args);这个方法 (重要)

```java protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException { if (this.logger.isTraceEnabled()) { this.logger.trace("Creating instance of bean '" + beanName + "'"); }

RootBeanDefinition mbdToUse = mbd;
Class resolvedClass = this.resolveBeanClass(mbd, beanName, new Class[0]);
// 确保 BeanDefinition 中的 Class 被加载
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
    mbdToUse = new RootBeanDefinition(mbd);
    mbdToUse.setBeanClass(resolvedClass);
}

try {
    //方法覆写相关 
    mbdToUse.prepareMethodOverrides();
} catch (BeanDefinitionValidationException var9) {
    throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(), beanName, "Validation of method overrides failed", var9);
}

Object beanInstance;
try {
    // InstantiationAwareBeanPostProcessor 这个地方也可以扩展 具体见上边提到的扩展点项目代码
    beanInstance = this.resolveBeforeInstantiation(beanName, mbdToUse);
    if (beanInstance != null) {
        return beanInstance;
    }
} catch (Throwable var10) {
    throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "BeanPostProcessor before instantiation of bean failed", var10);
}

try {
    //开始创建bean
    beanInstance = this.doCreateBean(beanName, mbdToUse, args);
    if (this.logger.isTraceEnabled()) {
        this.logger.trace("Finished creating instance of bean '" + beanName + "'");
    }

    return beanInstance;
} catch (ImplicitlyAppearedSingletonException | BeanCreationException var7) {
    throw var7;
} catch (Throwable var8) {
    throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", var8);
}

} ```

  • 紧接着我们看下 doCreateBean方法做了什么 注意 一些代码我直接略了 展开的话那真的说不完 这篇文章也写不完了~

```java protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException { BeanWrapper instanceWrapper = null; if (mbd.isSingleton()) { instanceWrapper = (BeanWrapper)this.factoryBeanInstanceCache.remove(beanName); }

if (instanceWrapper == null) {
    //<1>. 下边将会展开
    instanceWrapper = this.createBeanInstance(beanName, mbd, args);
}

Object bean = instanceWrapper.getWrappedInstance();
Class beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
    mbd.resolvedTargetType = beanType;
}

synchronized(mbd.postProcessingLock) {
    if (!mbd.postProcessed) {
        try {
            this.applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
        } catch (Throwable var17) {
            throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Post-processing of merged bean definition failed", var17);
        }

        mbd.postProcessed = true;
    }
}
// 下面这块代码是为了解决循环依赖的问题,以后有时间,我再对循环依赖这个问题进行解析吧
boolean earlySingletonExposure = mbd.isSingleton() && this.allowCircularReferences && this.isSingletonCurrentlyInCreation(beanName);
if (earlySingletonExposure) {
    if (this.logger.isTraceEnabled()) {
        this.logger.trace("Eagerly caching bean '" + beanName + "' to allow for resolving potential circular references");
    }

    this.addSingletonFactory(beanName, () -> {
        return this.getEarlyBeanReference(beanName, mbd, bean);
    });
}

Object exposedObject = bean;

try {
    //这一步也是非常关键的,这一步负责属性装配,因为前面的实例只是实例化了,并没有设值,这里就是设值
    //<2>. 下边将会展开
    this.populateBean(beanName, mbd, instanceWrapper);
    // 还记得 init-method 吗?还有 InitializingBean 接口
    // 这里就是处理 bean 初始化完成后的各种回调
    //<3>. 下边将会展开
    exposedObject = this.initializeBean(beanName, exposedObject, mbd);
} catch (Throwable var18) {
    if (var18 instanceof BeanCreationException && beanName.equals(((BeanCreationException)var18).getBeanName())) {
        throw (BeanCreationException)var18;
    }

    throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", var18);
}

if (earlySingletonExposure) {
    Object earlySingletonReference = this.getSingleton(beanName, false);
    if (earlySingletonReference != null) {
        if (exposedObject == bean) {
            exposedObject = earlySingletonReference;
        } else if (!this.allowRawInjectionDespiteWrapping && this.hasDependentBean(beanName)) {
            String[] dependentBeans = this.getDependentBeans(beanName);
            Set actualDependentBeans = new LinkedHashSet(dependentBeans.length);
            String[] var12 = dependentBeans;
            int var13 = dependentBeans.length;

            for(int var14 = 0; var14 < var13; ++var14) {
                String dependentBean = var12[var14];
                if (!this.removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
                    actualDependentBeans.add(dependentBean);
                }
            }

            if (!actualDependentBeans.isEmpty()) {
                throw new BeanCurrentlyInCreationException(beanName, "Bean with name '" + beanName + "' has been injected into other beans [" + StringUtils.collectionToCommaDelimitedString(actualDependentBeans) + "] in its raw version as part of a circular reference, but has eventually been wrapped. This means that said other beans do not use the final version of the bean. This is often the result of over-eager type matching - consider using 'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
            }
        }
    }
}

try {
    this.registerDisposableBeanIfNecessary(beanName, bean, mbd);
    return exposedObject;
} catch (BeanDefinitionValidationException var16) {
    throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", var16);
}

} ```

来我们看下 <1> 处 是如何创建bean的

```java protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) { Class> beanClass = this.resolveBeanClass(mbd, beanName, new Class[0]); //检查类的访问权限 if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Bean class isn't public, and non-public access not allowed: " + beanClass.getName()); } else { Supplier> instanceSupplier = mbd.getInstanceSupplier(); if (instanceSupplier != null) {

return this.obtainFromSupplier(instanceSupplier, beanName);
    } else if (mbd.getFactoryMethodName() != null) {
        //采用工厂方法实例化,注意,不是 FactoryBean
        return this.instantiateUsingFactoryMethod(beanName, mbd, args);
    } else {
        // 如果不是第一次创建,比如第二次创建 prototype bean。
        // 这种情况下,我们可以从第一次创建知道,采用无参构造函数,还是构造函数依赖注入 来完成实例化
        boolean resolved = false;
        boolean autowireNecessary = false;
        if (args == null) {
            synchronized(mbd.constructorArgumentLock) {
                if (mbd.resolvedConstructorOrFactoryMethod != null) {
                    resolved = true;
                    autowireNecessary = mbd.constructorArgumentsResolved;
                }
            }
        }

        if (resolved) {
            // 构造函数依赖注(无参构造)
            return autowireNecessary ? this.autowireConstructor(beanName, mbd, (Constructor[])null, (Object[])null) : this.instantiateBean(beanName, mbd);
        } else {
            // 判断是否采用有参构造函数
            Constructor[] ctors = this.determineConstructorsFromBeanPostProcessors(beanClass, beanName);
            if (ctors == null && mbd.getResolvedAutowireMode() != 3 && !mbd.hasConstructorArgumentValues() && ObjectUtils.isEmpty(args)) {
                ctors = mbd.getPreferredConstructors();
                return ctors != null ? this.autowireConstructor(beanName, mbd, ctors, (Object[])null) : this.instantiateBean(beanName, mbd);
            } else {
                //构造函数依赖注 (有参构造 )
                return this.autowireConstructor(beanName, mbd, ctors, args);
            }
        }
    }
}

} ```

  • 看下 instantiate 方法

```java public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) { if (!bd.hasMethodOverrides()) { Constructor constructorToUse; synchronized(bd.constructorArgumentLock) { constructorToUse = (Constructor)bd.resolvedConstructorOrFactoryMethod; if (constructorToUse == null) { Class> clazz = bd.getBeanClass(); if (clazz.isInterface()) { throw new BeanInstantiationException(clazz, "Specified class is an interface"); }

try {
                if (System.getSecurityManager() != null) {
                    clazz.getClass();
                    constructorToUse = (Constructor)AccessController.doPrivileged(() -> {
                        return clazz.getDeclaredConstructor();
                    });
                } else {
                    constructorToUse = clazz.getDeclaredConstructor();
                }

                bd.resolvedConstructorOrFactoryMethod = constructorToUse;
            } catch (Throwable var9) {
                throw new BeanInstantiationException(clazz, "No default constructor found", var9);
            }
        }
    }
    //利用构造来进行实例化 (反射)
    return BeanUtils.instantiateClass(constructorToUse, new Object[0]);
} else {
     // 存在方法覆写,利用 CGLIB 来完成实例化,需要依赖于 CGLIB 生成子类,这里就不展开了。
     // 注意: 如果不使用 CGLIB 的话,存在 override 的情况 JDK 并没有提供相应的实例化支持
    return this.instantiateWithMethodInjection(bd, beanName, owner);
}

} ```

  • 看看如何实例化bean的

SpringBoot源码之容器刷新 refreshContext 方法详解_第8张图片

接着跟进去

继续跟进去

SpringBoot源码之容器刷新 refreshContext 方法详解_第9张图片

继续

ok到此 我们已经把bean的实例化(也就是 createBeanInstance方法 )看完了 。注意 旁枝细节的就略过了看主要的就好

接着我们看下 bean是如何进行属性注入的

  • 该步骤主要是 populateBean(...) 方法,该方法负责进行属性设值,处理依赖。

```java protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) { // bean 实例的所有属性都在这里了 PropertyValues pvs = mbd.getPropertyValues();

if (bw == null) { if (!pvs.isEmpty()) { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance"); } else { return; } }

// 到这步的时候,bean 实例化完成(通过工厂方法或构造方法),但是还没开始属性设值, // InstantiationAwareBeanPostProcessor 的实现类可以在这里对 bean 进行状态修改, boolean continueWithPropertyPopulation = true; if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; // 如果返回 false,代表不需要进行后续的属性设值,也不需要再经过其他的 BeanPostProcessor 的处理 if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) { continueWithPropertyPopulation = false; break; } } } }

if (!continueWithPropertyPopulation) { return; }

if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIREBYNAME || mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIREBYTYPE) { MutablePropertyValues newPvs = new MutablePropertyValues(pvs);

// 通过名字找到所有属性值,如果是 bean 依赖,先初始化依赖的 bean。记录依赖关系
  if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
     autowireByName(beanName, mbd, bw, newPvs);
  }

  // 通过类型装配。复杂一些
  if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
     autowireByType(beanName, mbd, bw, newPvs);
  }

  pvs = newPvs;

}

boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors(); boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCYCHECKNONE);

if (hasInstAwareBpps || needsDepCheck) { PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching); if (hasInstAwareBpps) { for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; // 这里有个非常有用的 BeanPostProcessor 进到这里: AutowiredAnnotationBeanPostProcessor // 对采用 @Autowired、@Value 注解的依赖进行设值 pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName); if (pvs == null) { return; } } } } if (needsDepCheck) { checkDependencies(beanName, mbd, filteredPds, pvs); } } // 设置 bean 实例的属性值 applyPropertyValues(beanName, mbd, bw, pvs); } ```

SpringBoot源码之容器刷新 refreshContext 方法详解_第10张图片

@Autoware时候根据类型注入和根据name注入 是不是实际开发中都使用过呀

SpringBoot源码之容器刷新 refreshContext 方法详解_第11张图片

对采用 @Autowired、@Value 注解的依赖进行设值

SpringBoot源码之容器刷新 refreshContext 方法详解_第12张图片

属性注入完成后,这一步其实就是处理各种回调了 (通过这个回调 我们可以看到 光这里的扩展点就有多少。啧啧~~~)

```java protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) { if (System.getSecurityManager() != null) { AccessController.doPrivileged(new PrivilegedAction() { @Override public Object run() { invokeAwareMethods(beanName, bean); return null; } }, getAccessControlContext()); } else { // 如果 bean 实现了 BeanNameAware、BeanClassLoaderAware 或 BeanFactoryAware 接口,那么进行回调 invokeAwareMethods(beanName, bean); }

Object wrappedBean = bean; if (mbd == null || !mbd.isSynthetic()) { // BeanPostProcessor 的 postProcessBeforeInitialization 回调 wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); }

try { // 处理 bean 中定义的 init-method, // 或者如果 bean 实现了 InitializingBean 接口,调用 afterPropertiesSet() 方法 invokeInitMethods(beanName, wrappedBean, mbd); } catch (Throwable ex) { throw new BeanCreationException( (mbd != null ? mbd.getResourceDescription() : null), beanName, "Invocation of init method failed", ex); }

if (mbd == null || !mbd.isSynthetic()) { // BeanPostProcessor 的 postProcessAfterInitialization 回调 wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); } return wrappedBean; }

```

总结:

  • 最后我们以一张图来结束今天的文章 (文字总结就不做了看图即可)

说明: 关于扩展点的内容 请见我的下一篇文章 ~

本文完,如有错误恳请指正

本文部分参考了这位大佬的博文: https://javadoop.com/post/spring-ioc

你可能感兴趣的:(spring,boot,java,spring,后端,开发语言)