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

简介: 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 个人博客

目录
相关文章
|
7天前
|
Java 应用服务中间件 Nacos
Spring Cloud 常用各个组件详解及实现原理(附加源码+实现逻辑图)
Spring Cloud 常用各个组件详解及实现原理(附加源码+实现逻辑图)
21 0
|
10天前
|
监控 数据可视化 安全
一套成熟的Spring Cloud智慧工地平台源码,自主版权,开箱即用
这是一套基于Spring Cloud的智慧工地管理平台源码,具备自主版权,易于使用。平台运用现代技术如物联网、大数据等改进工地管理,服务包括建设各方,提供人员、车辆、视频监控等七大维度的管理。特色在于可视化管理、智能报警、移动办公和分布计算存储。功能涵盖劳务实名制管理、智能考勤、视频监控AI识别、危大工程监控、环境监测、材料管理和进度管理等,实现工地安全、高效的智慧化管理。
|
21小时前
|
设计模式 安全 Java
【初学者慎入】Spring源码中的16种设计模式实现
以上是威哥给大家整理了16种常见的设计模式在 Spring 源码中的运用,学习 Spring 源码成为了 Java 程序员的标配,你还知道Spring 中哪些源码中运用了设计模式,欢迎留言与威哥交流。
21 0
|
4天前
|
XML Java 数据格式
手写spring第七章-完成便捷实现bean对象初始化和销毁方法
手写spring第七章-完成便捷实现bean对象初始化和销毁方法
6 0
|
4天前
|
设计模式 存储 Java
手写spring第二章-运用设计模式编写可扩展的容器
手写spring第二章-运用设计模式编写可扩展的容器
7 0
|
5天前
|
XML 人工智能 Java
Spring Bean名称生成规则(含源码解析、自定义Spring Bean名称方式)
Spring Bean名称生成规则(含源码解析、自定义Spring Bean名称方式)
|
1月前
|
Java 应用服务中间件 Maven
SpringBoot 项目瘦身指南
SpringBoot 项目瘦身指南
46 0
|
2月前
|
缓存 Java Maven
Spring Boot自动配置原理
Spring Boot自动配置原理
48 0
|
1月前
|
缓存 安全 Java
Spring Boot 面试题及答案整理,最新面试题
Spring Boot 面试题及答案整理,最新面试题
120 0
|
1月前
|
前端开发 搜索推荐 Java
【Spring底层原理高级进阶】基于Spring Boot和Spring WebFlux的实时推荐系统的核心:响应式编程与 WebFlux 的颠覆性变革
【Spring底层原理高级进阶】基于Spring Boot和Spring WebFlux的实时推荐系统的核心:响应式编程与 WebFlux 的颠覆性变革