在idea中搜索了一下Spring的后置处理器(PostProcessor),找出了下图的几个


本文主要来分析红框中标出的两个,也就是在 refresh() 方法的第5步调用的后置处理器

1、后置处理器调用的时机

2、后置处理器调用的顺序

3、一个最重要的后置处理器

这个最重要的后置处理器就是 ConfigurationClassPostProcessor

1、ConfigurationClassPostProcessor的作用?

2、

4、案例读源码

(1)案例1

(2)案例2

(3)案例3

Spring Cloud中的案例一个,大家对Spring Cloud不熟悉没有关系,只需要关注Spring Framework部分就可以了

下面的代码是个 org.springframework.cloud.netflix.feign.ribbon包下的一个配置类(@Configuration),大家忽略Spring Cloud,就把它看做就是一个普通的配置类

@Configuration
class DefaultFeignLoadBalancedConfiguration {@Beand@ConditionalOnMissingBeanpublic Client feignClient(CachingSpringLoadBalancerFactory cachingFactory,SpringClientFactory clientFactory) {return new LoadBalancerFeignClient(new Client.Default(null, null),cachingFactory, clientFactory);}
}

下面启动时,我们在下面的方法上打上条件断点:org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader#loadBeanDefinitionsForConfigurationClass


调用栈如下

loadBeanDefinitionsForConfigurationClass:140, ConfigurationClassBeanDefinitionReader (o.s.context.annotation)
loadBeanDefinitions:116, ConfigurationClassBeanDefinitionReader (o.s.context.annotation)
processConfigBeanDefinitions:320, ConfigurationClassPostProcessor (o.s.context.annotation)
postProcessBeanDefinitionRegistry:228, ConfigurationClassPostProcessor (o.s.context.annotation)
invokeBeanDefinitionRegistryPostProcessors:272, PostProcessorRegistrationDelegate (o.s.context.support)
invokeBeanFactoryPostProcessors:92, PostProcessorRegistrationDelegate (o.s.context.support)
invokeBeanFactoryPostProcessors:687, AbstractApplicationContext (o.s.context.support)
refresh:525, AbstractApplicationContext (o.s.context.support)
refresh:122, EmbeddedWebApplicationContext (o.s.boot.context.embedded)
refresh:693, SpringApplication (o.s.boot)
refreshContext:360, SpringApplication (o.s.boot)
run:303, SpringApplication (o.s.boot)
run:1118, SpringApplication (o.s.boot)
run:1107, SpringApplication (o.s.boot)
main:21, AppBMain (com.yh.stu)

几种注册BD的方式

1、硬编码
通过BeanDefinitionRegistry.registerBeanDefinition硬编码的方式进行注册,通常的做法有:
1、Spring 本身在实例化AnnotationConfigApplicationContext时,根据环境情况硬编码注册4~7个BD

public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {...AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(BeanDefinitionRegistry registry, Object source) {...// 共注册了6个BD,即使通过RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);def.setSource(source);beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));...
}
private static BeanDefinitionHolder registerPostProcessor(BeanDefinitionRegistry registry, RootBeanDefinition definition, String beanName) {definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);registry.registerBeanDefinition(beanName, definition);return new BeanDefinitionHolder(definition, beanName);
}

我这里列出几个大家有个印象,后续用到这几个BD的时候知道怎么来的就可以了。

// 实现了两个接口:BeanDefinitionRegistryPostProcessor/BeanFactoryPostProcessor
1:org.springframework.context.annotation.ConfigurationClassPostProcessor
// 实现了BeanPostProcessor、BeanFactoryAware、PriorityOrdered接口
2:org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor
// 同2一样,实现了BeanPostProcessor、BeanFactoryAware、PriorityOrdered接口
3:org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor
// 同2一样,实现了BeanPostProcessor、BeanFactoryAware、PriorityOrdered接口
4:org.springframework.context.annotation.CommonAnnotationBeanPostProcessor
// 实现了SmartInitializingSingleton, ApplicationContextAware 接口
5:org.springframework.context.event.EventListenerMethodProcessor 6:org.springframework.context.event.DefaultEventListenerFactory

❓ 1-这些Spring内部的 Bean是什么时候实例化的呢?
❓ 2-自定义的 BeanFacotryPostProcessor 是什么时候实例化的呢?

答1:
(1)、内部BeanFacotryPostProcessor 是在其被调用的时候利用容器(beanFactory.getBean(…))进行实例化的。
(和普通的Bean不一样,普通的Bean都是在refresh的第11阶段,即在finishBeanFactoryInitialization(beanFactory)方法中进行的)

//org.springframework.context.support.PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors
public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors){...// 从容器中找出所有 BeanDefinitionRegistryPostProcessor 类型的BD,后续按照顺序实例化并调用(PriorityOrdered/Ordered)String[] postProcessorNames =beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);for (String ppName : postProcessorNames) {if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {// 使用getBean来实例化BeancurrentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));processedBeans.add(ppName);}}...
}

(2)、AutowiredAnnotationBeanPostProcessor 是在 refresh的第 6 阶段,即在registerBeanPostProcessors(beanFactory)方法中实例化的

//org.springframework.context.support.PostProcessorRegistrationDelegate#registerBeanPostProcessors
public static void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {// 从容器中找出所有 BeanPostProcessor 类型的BD,后续按照顺序调用(PriorityOrdered/Ordered)String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);...//遍历到 org.springframework.context.annotation.internalAutowiredAnnotationProcessorfor (String ppName : postProcessorNames) {if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {// 使用getBean来实例化BeanBeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);}...}

(3)同2一样
(4)同2一样
(5)EventListenerMethodProcessor 类的实例化时在refresh() 方法的第 11 阶段,即finishBeanFactoryInitialization(beanFactory) 方法中将其作为普通的Bean进行实例化

2、在容器中配置
Spring中配置Bean,在调用后置处理器 Configuration

2.5、调用后置处理器相关推荐

  1. Spring的9处调用后置处理器

    在Sping的整个生命周期中,有9个地方调用后置处理器.这些后置处理器是spring实现自定义功能或者扩展spring的核心所在 一.实例化前 该方法属于InstantiationAwareBeanP ...

  2. spring--bean后置处理器(BeanPostProcessor)原理解析

    文章目录 功能描述: 如何使用: 定义要处理的接口类型 添加实际需要处理的类 定义后置处理器 编写测试类 执行日志 后置处理器加载解析 registerBeanPostProcessors注册拦截be ...

  3. spring源码:九大后置处理器

    目的: spring在完成一个bean的初始化.实例化的过程中,会用到九个后置处理器:本文梳理出这九个后置处理器 九大后置处理器 spring在初始化的过程中,会在九个地方分别调用了五个后置处理的九个 ...

  4. 攀登Spring珠穆朗玛峰:前置与后置处理器

    文章目录 Spring的前置与后置处理器 前提知识 前置与后置处理器定义 前置处理器:BeanFactoryPostProcessor `postProcessBeanFactory`调用 后置处理器 ...

  5. Spring容器创建流程(4)调用beanFactory后置处理器

    postProcessBeanFactory() 方法留给子类去实现. invokeBeanFactoryPostProcessors() 调用bean工厂的后置处理器(以前的执行流程可在系列文章中查 ...

  6. 实验10:创建带有生命周期方法的bean ||实验11:测试bean的后置处理器

    实验10:创建带有生命周期方法的bean 实验11:测试bean的后置处理器 MyBeanPostProcessor.java package com.atguigu.bean;import org. ...

  7. Spring学习笔记八--Bean生命周期和后置处理器

    为什么80%的码农都做不了架构师?>>>    Bean生命周期和后置处理器 IOC容器的bean生命周期 1.构造器或工厂方法建立bean实例 2.bean属性赋值,引用其他bea ...

  8. SringIOC中Bean的后置处理器

    Bean后置处理器 Spring提供的特殊的Bean 1. Bean后置处理器允许在调用初始化方法 即:bean节点init-method属性对应的方法的前后,对Bean进行额外的处理. 2.Bean ...

  9. 【Spring注解系列11】Spring后置处理器BeanPostProcessor用法与原理

    1.BeanPostProcessor原理 先说,bean的后置处理器BeanPostProcessor接口中两个方法: postProcessBeforeInitialization:在初始化之前工 ...

最新文章

  1. 安装python环境及pip_Python环境搭建及pip的使用
  2. echarts控制只显示部分数据的折线图_Python数据可视化之pyecharts入门
  3. AndroidStudio+ideasmali动态调试smali汇编
  4. 【caffe】找不到gpu/mxGPUArray.h
  5. AWR 报告深度解读:Time Model Statistics 信息的计算和获取
  6. 8.1 模型压缩的方法
  7. Android平台支持的多媒体格式
  8. 软件(自动化)测试面试基础知识点汇总
  9. c语言悔棋用栈,中国象棋人机博弈程序(扁平化棋局) C语言实现
  10. java rf14bug_让云平台发生重大宕机事故的15个方法
  11. 值得收藏,学术论文投稿前必看,最全准备材料~
  12. vscode 设置关键字高亮显示
  13. 最近 火火火 的开源项目
  14. python自动化测试面试题None is ==详解
  15. maya扇子动画_MAYA制作动画的十大原理!
  16. Spring Boot+Vue项目打包部署
  17. 高等数学学习笔记——第六十四讲——偏导数
  18. IDL和MATLAB读取grib数据
  19. arm指令集:精简指令集、复杂指令集
  20. Beacon学习总结

热门文章

  1. python 课堂笔记 420_一位初学Python同学的课堂笔记,仿佛看到当年的自己
  2. mysql 双机备份_mysql双机热备详解及延伸备份
  3. jni android rect.h,解决 fatal error: jni_md.h: No such file or directory #include “jni_md.h”
  4. 51单片机c语言程序控制,51单片机C语言编程基础及实例.pdf
  5. attrib批量显示文件夹_Windows 下彻底隐藏文件和文件夹的方法
  6. kafka集群部署成功后,创建生产者往指定主题里面发送消息时出错
  7. Linux中的df命令
  8. flutter能开发游戏吗_不用 H5,闲鱼 Flutter 如何玩转小游戏?-阿里云开发者社区...
  9. ftp ---- vsftpd安装卸载
  10. openssl以及openssh升级