Spring 核心方法 refresh 刷新流程简要概述及相关源码扩展实现(一)(下)

本文涉及的产品
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: Spring 核心方法 refresh 刷新流程简要概述及相关源码扩展实现(一)

prepareBeanFactory

BeanFactory 准备工作,对 BeanFactory 各种属性进行填充

源码解析

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
  // 设置 beanFactory 的 classloader 为当前 context 的 classloader
  beanFactory.setBeanClassLoader(getClassLoader());
  // 设置 BeanFactory 表达式语言处理器
  beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
  // 为 beanFactory 增加一个默认的 propertyEditor,这个主要是对 bean 属性等设置管理的一个工具类
  beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
  // Configure the bean factory with context callbacks.
  // 添加 beanPostProcessor,ApplicationContextAwareProcessor 此类用来完成某些Aware对象的注入
  // postProcessBeforeInitialization 方法执行某些 Aware 对象的属性注入,实例化之后-初始化之前调用
  beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
  // 设置要忽略自动装配的接口,为什么此处要对这些接口进行忽略,原因非常简单,这些接口的实现是由容器通过set 方法进行注入的,
  // 所以在使用 autowire 进行注入的时候需要将这些接口进行忽略
  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.
  // 设置几个自动装配的特殊规则,当在进行ioc初始化的如果有多个实现,那么就使用指定的对象进行注入
  beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
  beanFactory.registerResolvableDependency(ResourceLoader.class, this);
  beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
  beanFactory.registerResolvableDependency(ApplicationContext.class, this);
  // Register early post-processor for detecting inner beans as ApplicationListeners.
  // 注册BPP
  beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
  // 增加对AspectJ的支持,在java中织入分为三种方式,分为编译器织入,类加载器织入,运行期织入,
  // 编译器织入:指在java编译器,采用特殊的编译器,将切面织入到java类中,
  // 类加载期织入:指通过特殊的类加载器,在类字节码加载到JVM时,织入切面,
  // 运行期织入:采用cglib和jdk进行切面的织入
  // aspectj 提供了两种织入方式,
  // 第一种是通过特殊编译器,在编译器,将aspectj语言编写的切面类织入到java类中,
  // 第二种是类加载期织入,就是下面的 load time weaving,此处后续讲
  if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
    beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
    // Set a temporary ClassLoader for type matching.
    beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
  }
  // 注册默认的系统环境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());
  }
}
  1. beanFactory#setBeanClassLoader(getClassLoader()):设置 BeanFactory 所需的类加载器【线程上下文加载器—>当前类的类加载器—>系统类加载器】
  2. beanFactory#setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader())):Bean 定义值中表达式语言的解析策略,SpringBoot 默认使用的是 StandardBeanExpressionResolver
  3. beanFactory#addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment())):为 BeanFactory 增加一个默认的 propertyEditor(属性编辑器)这个主要是用来管理 Bean 属性等的工具类【这个地方可以作为扩展点】
  4. beanFactory#addBeanPostProcessor(new ApplicationContextAwareProcessor(this)):新增 BPP,ApplicationContextAwareProcessor 此类用来完成某些 Aware 对象的注入,在 postProcessBeforeInitialization 方法中执行某些 Aware 属性的注入,在实例化之后、执行初始化方法之前进行调用
  5. beanFactory#ignoreDependencyInterface:设置要忽略自动装配的接口,忽略的原因非常简单,这些接口的实现是由容器通过 set 方法进行注入的,所以在使用 autowire 进行注入时需要将这些接口忽略.

EnvironmentAware、EmbeddedValueResolverAware、ResourceLoaderAware、ApplicationEventPublisherAware、MessageSourceAware、ApplicationContextAware

还有一些 aware 接口是在执行初始化时也就是调用 invokeAwareMethods 方法时【BeanNameAware、BeanClassLoaderAware、BeanFactoryAware】进行注入.

  1. beanFactory#addBeanPostProcessor(new ApplicationListenerDetector(this)):注册 BPP,该类 ApplicationListenerDetector 作用用来检测 bean 是否实现了 ApplicationListener 接口,有两个作用,如下:
    实例化完成之后,如果 bean 是单例的并且属于 ApplicationListener 接口,则加入到多播器中
    bean 销毁之前,如果 bean 是一个 applicationListener,则从多播器中提前删除
  2. beanFactory#addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory)):增加对 AspectJ 的支持,【AspectJ 提供了两种织入方式:1、通过特殊的加载器,将 aspectj 语言编写的切面类织入到 Java 类中;2、类加载器织入,就是 load time weaving】在 Java 中织入分为三种方式
    编译器织入:在 Java 编译器,采用特殊的编译器,将切面织入到 Java 类中
    类加载器织入:通过特殊的类加载器,将类字节码加载到 JVM 时,织入切面
    运行期织入:采用 CGLIB、JDK 进行切面织入
  3. beanFactory#registerSingleton【environment、systemProperties、systemEnvironment】:注册默认的系统环境 bean 到一级缓存中

扩展 BeanPostProcessor 对 Bean 进行增强

Aware 相关的在 invokeAwareMethods 方法中只会执行 BeanNameAware、BeanClassLoaderAware、BeanFactoryAware,其他定义的 Aware 接口会在 ApplicationContextAwareProcessor.postProcessBeforeInitialization 中执行

扩展 BeanPostProcessor「简称:BPP」,其实就是实现 BPP 接口,在实现的方法编写自己需要扩展的逻辑

public class MyBeanPostProcessor implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("postProcessBeforeInitialization---MyBeanPostProcessor");
        return bean;
    }
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("postProcessAfterInitialization---MyBeanPostProcessor");
        if (bean instanceof Person) {
            Person person = (Person) bean;
            person.setName("哈哈哈");
            System.out.println("postProcessAfterInitialization#person:" + person.getName());
            return person;
        } else {
            return bean;
        }
    }
}

在 SpringMVC 中通过 XML 文件配置使其能够被 Spring 所读取

<bean class="com.mashibing.MyBeanPostProcessor"/>

在 SpringBoot 中通过注解 @Configuration 或 @Import 导入该类型即可.

postProcessBeanFactory

此方法交由子类去实现做额外的处理,此处我们一般不做任何扩展工作,但是在 Web 中的代码,是由具体的实现的.

protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
  super.postProcessBeanFactory(beanFactory);
  // scanner=ClassPathBeanDefinitionScanner
  if (this.basePackages != null && this.basePackages.length > 0) {
    this.scanner.scan(this.basePackages);
  }
  // reader=AnnotatedBeanDefinitionReader
  if (!this.annotatedClasses.isEmpty()) {
    this.reader.register(ClassUtils.toClassArray(this.annotatedClasses));
  }
}

AnnotatedBeanDefinitionReader 类作用:直接将指定的某个没有使用 spring 提供的 @Bean 、@Component 等注解的类解析成 BeanDefinition 对象并保存到容器中,如果被解析的类上有 spring 其他注解,也会被解析,保存到 BeanDefinition 以后,后面会经过 Spring Bean 整个生命周期进行 Bean 实例构建.

ClassPathBeanDefinitionScanner 类作用:扫描指定包路径下的 @Component 注解,将有这个注解的类解析成 BeanDefinition 对象并放入容器中

invokeBeanFactoryPostProcessors

此方法是执行 BeanFactoryPostProcessor「BFPP」 方法的入口,调用各种 BeanFactory 处理器,会在这里面完成属性的 ${} 的解析工作

源码分析

protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
  // 获取到当前应用程序上下文的 beanFactoryPostProcessors 集合的值,并且实例化调用执行所有已经注册的 beanFactoryPostProcessor
  PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
  // Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
  // (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
  if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
    beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
    beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
  }
}

默认情况下,通过 getBeanFactoryPostProcessors 方法来获取已经注册的 BFPP,但是默认是空的,那么问题来了,如果你想扩展,怎么进行扩展工作?

  1. 新增扩展类实现 BeanFactoryPostProcessors 方法通过 XML 配置文件注入能够被 Spring 识别到,后面进行 Bean 加载「该方式配置的 Bean 不会被添加到 beanFactoryPostProcessors 集合中」
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
   @Override
   public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
       System.out.println("扩展 BeanFactoryPostProcessor");
   }
}
<bean class="com.mashibing.MyBeanFactoryPostProcessor"/>
  1. 继承父类写入 super#addBeanFactoryPostProcessor 方法 「该配置引入的 Bean 会被添加进 beanFactoryPostProcessors 集合中」
ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("test.xml");
ac.addBeanFactoryPostProcessor(new MyBeanFactoryPostProcessor());
ac.refresh();

将 XML 配置的类去除即可.

实现 BFPP(BeanFactoryPostProcessor)比较重要的有这个类:ConfigurationClassPostProcessor【1、解析加了 @Configuration 的配置类;2、解析 @ComponentScan 扫描的包;3、解析 @ComponentScans 扫描的包;4、解析 @Import 注解】该类是用于 SpringBoot 自动装配过程中的核心类

ConfigurationClassPostProceesor 核心类流程详解:Spring 核心类 ConfigurationClassPostProcessor 流程讲解及源码全面分析

invokeBeanFactoryPostProcessors 执行流程

在学习分析该方法核心流程之前,我们先要区分两个类的作用,BeanFactoryPostProcessor 与 BeanDefinitionRegistryPostProcessor 区别

  • BeanFactoryPostProcessor 用于操作 BeanFactory,BeanFactory 中包含了 BeanDefinition,里面有 definitionNames、definitionMaps 两个集合
  • BeanDefinitionRegistryPostProcessor 是 BeanFactoryPostProcessor 下的子接口,它在常规 BeanFactoryPostProcessor 之前检测之前注册的 Bean 定义信息,如果一个 Bean 实现了 BeanDefinitionRegistryPostProcessor 子接口,那么它的 postProcessBeanDefinitionRegistry 方法可以和 BFPP#postProcessBeanFactory 方法一起执行
public static void invokeBeanFactoryPostProcessors(
       ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
    // 无论是什么情况,优先执行 BeanDefinitionRegistryPostProcessors
    // 将已经执行过的BFPP存储在 processedBeans 中,防止重复执行
    Set<String> processedBeans = new HashSet<>();
    // 此处是 DefaultListableBeanFactory,实现了 BeanDefinitionRegistry 接口,所以为 true
    if (beanFactory instanceof BeanDefinitionRegistry) {
        // 类型转换
        BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
        // 存放 BeanFactoryPostProcessor 的集合
        List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
        // 存放 BeanDefinitionRegistryPostProcessor 的集合
        List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
        // 首先处理入参中的 beanFactoryPostProcessors,遍历所有的 beanFactoryPostProcessors,将BeanDefinitionRegistryPostProcessor 和 BeanFactoryPostProcessor 区分开
        for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
            // 如果是 BeanDefinitionRegistryPostProcessor
            if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
                BeanDefinitionRegistryPostProcessor registryProcessor =
                        (BeanDefinitionRegistryPostProcessor) postProcessor;
                // 直接执行 BeanDefinitionRegistryPostProcessor 接口中的postProcessBeanDefinitionRegistry 方法
                registryProcessor.postProcessBeanDefinitionRegistry(registry);
                // 添加到 registryProcessors,用于后续执行 postProcessBeanFactory 方法
                registryProcessors.add(registryProcessor);
            } else {
                // 否则,只是普通的BeanFactoryPostProcessor,添加到regularPostProcessors,用于后续执行postProcessBeanFactory方法
                regularPostProcessors.add(postProcessor);
            }
        }
        // 用于保存本次要执行的 BeanDefinitionRegistryPostProcessor
        List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
        // 调用所有实现PriorityOrdered接口的BeanDefinitionRegistryPostProcessor实现类
        // 找到所有实现BeanDefinitionRegistryPostProcessor接口bean的beanName
        String[] postProcessorNames =
               beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
        // 遍历处理所有符合规则的postProcessorNames
        for (String ppName : postProcessorNames) {
            // 检测是否实现了 PriorityOrdered 接口
            if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                // 获取名字对应的bean实例,添加到currentRegistryProcessors中
                currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                // 将要被执行的BFPP名称添加到processedBeans,避免后续重复执行
                processedBeans.add(ppName);
            }
        }
        // 按照优先级进行排序操作
        sortPostProcessors(currentRegistryProcessors, beanFactory);
        // 添加到registryProcessors中,用于最后执行postProcessBeanFactory方法
        registryProcessors.addAll(currentRegistryProcessors);
        // 遍历currentRegistryProcessors,执行postProcessBeanDefinitionRegistry方法
        invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
        // 执行完毕之后,清空currentRegistryProcessors
        currentRegistryProcessors.clear();
        // 找到所有实现BeanDefinitionRegistryPostProcessor接口bean的beanName,此处需要重复查找的原因在于上面的执行过程中可能会新增其他的 BeanDefinitionRegistryPostProcessor
        // 在 MyBeanDefinitionRegistryPostProcessor 类实现新增
        postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
        for (String ppName : postProcessorNames) {
            // 检测是否实现了Ordered接口,并且还未执行过
            if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
                // 获取名字对应的bean实例,添加到currentRegistryProcessors中
                currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                // 将要被执行的BFPP名称添加到processedBeans,避免后续重复执行
                processedBeans.add(ppName);
            }
        }
        // 按照优先级进行排序操作
        sortPostProcessors(currentRegistryProcessors, beanFactory);
        // 添加到registryProcessors中,用于最后执行postProcessBeanFactory方法
        registryProcessors.addAll(currentRegistryProcessors);
        // 遍历currentRegistryProcessors,执行postProcessBeanDefinitionRegistry方法
        invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
        // 执行完毕之后,清空currentRegistryProcessors
        currentRegistryProcessors.clear();
        // 最后,调用所有剩下的BeanDefinitionRegistryPostProcessors
        boolean reiterate = true;
        while (reiterate) {
            reiterate = false;
            // 找出所有实现BeanDefinitionRegistryPostProcessor接口的类
            postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
            // 遍历执行
            for (String ppName : postProcessorNames) {
                // 跳过已经执行过的BeanDefinitionRegistryPostProcessor
                if (!processedBeans.contains(ppName)) {
                    // 获取名字对应的bean实例,添加到currentRegistryProcessors中
                    currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                    // 将要被执行的BFPP名称添加到processedBeans,避免后续重复执行
                    processedBeans.add(ppName);
                    reiterate = true;
                }
            }
            // 按照优先级进行排序操作
            sortPostProcessors(currentRegistryProcessors, beanFactory);
            // 添加到registryProcessors中,用于最后执行postProcessBeanFactory方法
            registryProcessors.addAll(currentRegistryProcessors);
            // 遍历currentRegistryProcessors,执行postProcessBeanDefinitionRegistry方法
            invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
            // 执行完毕之后,清空currentRegistryProcessors
            currentRegistryProcessors.clear();
        }
        // 调用所有BeanDefinitionRegistryPostProcessor的postProcessBeanFactory方法
        invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
        // 最后,调用入参beanFactoryPostProcessors中的普通BeanFactoryPostProcessor的postProcessBeanFactory方法
        invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
    } else {
        // Invoke factory processors registered with the context instance.
        // 如果beanFactory不归属于BeanDefinitionRegistry类型,那么直接执行postProcessBeanFactory方法
        invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
    }
    // 到这里为止,入参 beanFactoryPostProcessors 和容器中的所有BeanDefinitionRegistryPostProcessor 已经全部处理完毕,下面开始处理容器中所有的 BeanFactoryPostProcessor
    // 可能会包含一些实现类,只实现了 BeanFactoryPostProcessor,并没有实现 BeanDefinitionRegistryPostProcessor 接口
    // 找到所有实现BeanFactoryPostProcessor接口的类
    // 自身 new 出来的 BFPP 无法匹配到,只会匹配到交由 Bean 容器管理的对象
    String[] postProcessorNames =
            beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
    // 用于存放实现了PriorityOrdered接口的BeanFactoryPostProcessor
    List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
    // 用于存放实现了Ordered接口的BeanFactoryPostProcessor的beanName
//    List<String> orderedPostProcessorNames = new ArrayList<>();
    List<BeanFactoryPostProcessor> orderedPostProcessor = new ArrayList<>();
    // 用于存放普通BeanFactoryPostProcessor的beanName
//    List<String> nonOrderedPostProcessorNames = new ArrayList<>();
    List<BeanFactoryPostProcessor> nonOrderedPostProcessorNames = new ArrayList<>();
    // 遍历 postProcessorNames,将 BeanFactoryPostProcessor 按实现 PriorityOrdered、实现Ordered 接口、普通三种区分开
    for (String ppName : postProcessorNames) {
        // 跳过已经执行过的BeanFactoryPostProcessor
        if (processedBeans.contains(ppName)) {
            // skip - already processed in first phase above
        }
        // 添加实现了PriorityOrdered接口的BeanFactoryPostProcessor到priorityOrderedPostProcessors
        else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
            priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
        }
        // 添加实现了Ordered接口的BeanFactoryPostProcessor的beanName到orderedPostProcessorNames
        else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
//        orderedPostProcessorNames.add(ppName);
            orderedPostProcessor.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
        } else {
            // 添加剩下的普通BeanFactoryPostProcessor的beanName到nonOrderedPostProcessorNames
//        nonOrderedPostProcessorNames.add(ppName);
            nonOrderedPostProcessorNames.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
        }
    }
    // 对实现了PriorityOrdered接口的BeanFactoryPostProcessor进行排序
    sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
    // 遍历实现了 PriorityOrdered 接口的 BeanFactoryPostProcessor,执行 postProcessBeanFactory 方法
    invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
    // 创建存放实现了Ordered接口的BeanFactoryPostProcessor集合
//    List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
    // 遍历存放实现了Ordered接口的BeanFactoryPostProcessor名字的集合
//    for (String postProcessorName : orderedPostProcessorNames) {
    // 将实现了Ordered接口的BeanFactoryPostProcessor添加到集合中
//      orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
//    }
    // 对实现了Ordered接口的BeanFactoryPostProcessor进行排序操作
    sortPostProcessors(orderedPostProcessor, beanFactory);
    // 遍历实现了Ordered接口的BeanFactoryPostProcessor,执行postProcessBeanFactory方法
//    invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
    invokeBeanFactoryPostProcessors(orderedPostProcessor, beanFactory);
    // Finally, invoke all other BeanFactoryPostProcessors.
    // 最后,创建存放普通的BeanFactoryPostProcessor的集合
//    List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
    // 遍历存放实现了普通BeanFactoryPostProcessor名字的集合
//    for (String postProcessorName : nonOrderedPostProcessorNames) {
    // 将普通的BeanFactoryPostProcessor添加到集合中
//      nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
//    }
    // 遍历普通的BeanFactoryPostProcessor,执行postProcessBeanFactory方法
//    invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
    invokeBeanFactoryPostProcessors(nonOrderedPostProcessorNames, beanFactory);
    // 清除元数据缓存(mergeBeanDefinitions、allBeanNamesByType、singletonBeanNameByType)
    // 因为后置处理器可能已经修改了原始元数据,例如,替换值中的占位符
    beanFactory.clearMetadataCache();
}

源码中 PriorityOrdered、Ordered、nonOrdered 的 BFPP 对象,都分别用不同的循环进行遍历 getBean,此处调整了源码,将这三种类型的对象放在一个循环里面进行处理,增加多重 if 判别存入到不同的集合中

以下对源码中的流程进行流程图的解析,以及详细的文档说明

  • 创建一个空的集合,用来存储已经执行过的 BFPP 或 BDRPP
  • 判断当前 BeanFactory 是否是 BeanDefinitionRegistry 类型,此处是 DefaultListableBeanFactory,实现了 BeanDefinitionRegistry 接口,所以为 true
  • 创建两个集合用于存放不同的接口,分别是存储 BFPP(BeanFactoryPostProcessor)接口的 regularPostProcessors,另外一个是 存储 BDRPP(BeanDefinitionRegistryPostProcessor)接口的 registryProcessors;存储到这两个集合中的类只是为了方便执行 BFPP 下的 postProcessBeanFactory 方法

  • 先处理用户自定义的 BFPP 集合,遍历每一个元素,先判定其是否为 BDRPP 类型:如果是就执行 postProcessBeanDefinitionRegistry 方法并将其添加进 registryProcessors 集合中;如果不是就将其添加进 regularPostProcessors 即可
  • 单独创建一个集合对象,用于存放当前需要执行的 BDRPP 对象:currentRegistryProcessors
  • 获取当前容器中实现了 BDRPP 接口的 beanName1、判定是否存在实现了PriorityOrdered接口的 beanName:如果有就通过 beanName 进行 getBean 操作【getBean->doGetBean->createBean->doCreateBean】,将其添加进 currentRegistryProcessors 集合中,再添加到 processedBeans 集合中【避免后续重复执行】2、判断是否存在实现了Ordered接口的 beanName:如果有就通过 beanName 进行 getBean 操作【getBean->doGetBean->createBean->doCreateBean】,将其添加进 currentRegistryProcessors 集合中,再添加到 processedBeans 集合中【避免后续重复执行】3、找出剩下所有实现 BDRPP 接口的类,直至所有的方法所被找到并且执行完毕4、1-2-3 步骤取出对应的接口出来以后,都要经过如下的流程去处理
  • 对 currentRegistryProcessors 进行排序
  • registryProcessors 将 currentRegistryProcessors 所有元素添加进去
  • 遍历调用且执行 currentRegistryProcessors 集合每一个元素的 postProcessBeanDefinitionRegistry 方法
  • 清空 currentRegistryProcessors,避免重复添加,方便下面新增
  • 5、调用所有 BeanDefinitionRegistryPostProcessor#postProcessBeanFactory 方法
    6、最后,调用入参 beanFactoryPostProcessors 中的普通 BeanFactoryPostProcessor#postProcessBeanFactory 方法
    7、到这里为止,入参中所有的 BFPP 和容器中所有的 BDRPP 都已经全部处理完毕

以下的流程是处理容器中的 BFPP 接口

处理容器中的 BFPP【自身 new 出来的入参时会携带进来,下面的都是被容器所管理的 BFPP】

  • 判定是否是实现 PriorityOrdered 接口的 beanName,如果是将其放入 priorityOrderedPostProcessors 集合中
  • 判定是否是实现 Ordered 接口的 beanName,如果是将其放入 Ordered 对应的集合中
  • 如果以上两者都不是,存入到另外一个集合中
  • 按照以上三点的先后顺序,对各自的集合先进行排序(nonOrdered 元素不需要进行排序),对集合进行遍历且调用具体的 postProcessBeanFactory 方法执行

扩展 BeanDefinitionRegistryPostProcessor

实现 BDRPP 接口的类可以调用 registry.registerBeanDefinition 来新增 BeanDefinition 信息,配置它的同时新增的类也可以被 Spring 被所识别

// 该类需要在 XML 配置,使其能够让 Spring 识别
public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor, PriorityOrdered {
    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
        System.out.println("执行postProcessBeanDefinitionRegistry---MyBeanDefinitionRegistryPostProcessor");
        // 引入了一个新的 BDRPP 实现类
        BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(MySelfBeanDefinitionRegistryPostProcessor.class);
        builder.addPropertyValue("name","zhangsan");
        registry.registerBeanDefinition("vnjohn",builder.getBeanDefinition());
    }
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        System.out.println("执行postProcessBeanFåactory---MyBeanDefinitionRegistryPostProcessor");
        BeanDefinition msb = beanFactory.getBeanDefinition("vnjohn");
        msb.getPropertyValues().getPropertyValue("name").setConvertedValue("lisi");
        System.out.println("===============");
    }
    @Override
    public int getOrder() {
        return 0;
    }
}
// 该类不需要进行配置,会在循环查找 BDRPP 时被找到
public class MySelfBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor, PriorityOrdered {
    private String name;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
        System.out.println("调用执行postProcessBeanDefinitionRegistry--MySelfBeanDefinitionRegistryPostProcessor");
        // 这里可以继续进行扩展新增 BDRPP 实现类
        // BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(MySelfTwoBeanDefinitionRegistryPostProcessor.class);
        // builder.addPropertyValue("nickName","vnjohn");
        // registry.registerBeanDefinition("mySelfTwo",builder.getBeanDefinition());
    }
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        System.out.println("调用执行postProcessBeanFactory--MySelfBeanDefinitionRegistryPostProcessor");
    }
    @Override
    public int getOrder() {
        return 0;
    }
}
<bean class="com.mashibing.selfbdrpp.MyBeanDefinitionRegistryPostProcessor"/>

总结

由于 refresh 涉及到了 13 个方法,在一篇文章里进行分解内容会过长,分为两个章节,剩下的 registerBeanPostProcessors、initMessageSource、initApplicationEventMulticaster、onRefresh、registerListeners、finishBeanFactoryInitialization、finishRefresh 方法在章节二进行剖析

记录个人在学习 Spring 源码时整理出来的详细笔记,整理文章不易,喜欢的可以点个关注和赞👍哦,不喜勿喷!

更多技术文章可以查看:vnjohn 个人博客

目录
相关文章
|
29天前
|
监控 Java 应用服务中间件
高级java面试---spring.factories文件的解析源码API机制
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置、起步依赖和内嵌服务器等特性,极大地简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是spring.factories文件的解析源码API机制。
67 2
|
1月前
|
数据采集 监控 前端开发
二级公立医院绩效考核系统源码,B/S架构,前后端分别基于Spring Boot和Avue框架
医院绩效管理系统通过与HIS系统的无缝对接,实现数据网络化采集、评价结果透明化管理及奖金分配自动化生成。系统涵盖科室和个人绩效考核、医疗质量考核、数据采集、绩效工资核算、收支核算、工作量统计、单项奖惩等功能,提升绩效评估的全面性、准确性和公正性。技术栈采用B/S架构,前后端分别基于Spring Boot和Avue框架。
|
13天前
|
存储 缓存 Java
Spring面试必问:手写Spring IoC 循环依赖底层源码剖析
在Spring框架中,IoC(Inversion of Control,控制反转)是一个核心概念,它允许容器管理对象的生命周期和依赖关系。然而,在实际应用中,我们可能会遇到对象间的循环依赖问题。本文将深入探讨Spring如何解决IoC中的循环依赖问题,并通过手写源码的方式,让你对其底层原理有一个全新的认识。
30 2
|
1月前
|
前端开发 Java 开发者
Spring生态学习路径与源码深度探讨
【11月更文挑战第13天】Spring框架作为Java企业级开发中的核心框架,其丰富的生态系统和强大的功能吸引了无数开发者的关注。学习Spring生态不仅仅是掌握Spring Framework本身,更需要深入理解其周边组件和工具,以及源码的底层实现逻辑。本文将从Spring生态的学习路径入手,详细探讨如何系统地学习Spring,并深入解析各个重点的底层实现逻辑。
59 9
|
2月前
|
Java Spring
Spring底层架构源码解析(三)
Spring底层架构源码解析(三)
142 5
|
2月前
|
XML Java 数据格式
Spring底层架构源码解析(二)
Spring底层架构源码解析(二)
|
2月前
|
Java 数据库连接 数据库
让星星⭐月亮告诉你,SSH框架01、Spring概述
Spring是一个轻量级的Java开发框架,旨在简化企业级应用开发。它通过IoC(控制反转)和DI(依赖注入)降低组件间的耦合度,支持AOP(面向切面编程),简化事务管理和数据库操作,并能与多种第三方框架无缝集成,提供灵活的Web层支持,是开发高性能应用的理想选择。
40 1
|
2月前
|
XML Java 数据格式
手动开发-简单的Spring基于注解配置的程序--源码解析
手动开发-简单的Spring基于注解配置的程序--源码解析
48 0
|
2月前
|
人工智能 自然语言处理 前端开发
SpringBoot + 通义千问 + 自定义React组件:支持EventStream数据解析的技术实践
【10月更文挑战第7天】在现代Web开发中,集成多种技术栈以实现复杂的功能需求已成为常态。本文将详细介绍如何使用SpringBoot作为后端框架,结合阿里巴巴的通义千问(一个强大的自然语言处理服务),并通过自定义React组件来支持服务器发送事件(SSE, Server-Sent Events)的EventStream数据解析。这一组合不仅能够实现高效的实时通信,还能利用AI技术提升用户体验。
219 2
|
1天前
|
NoSQL Java Redis
Spring Boot 自动配置机制:从原理到自定义
Spring Boot 的自动配置机制通过 `spring.factories` 文件和 `@EnableAutoConfiguration` 注解,根据类路径中的依赖和条件注解自动配置所需的 Bean,大大简化了开发过程。本文深入探讨了自动配置的原理、条件化配置、自定义自动配置以及实际应用案例,帮助开发者更好地理解和利用这一强大特性。
28 14