kafka消息顺序问题,从理论到实践!

简介: kafka消息顺序问题,从理论到实践!

二、Spring生命周期的大胆猜测

这里分享一个阅读源码的小技巧:捉大放小,连蒙带猜!8字真言,我们在阅读源码过程中,因为你要知道,每一个被开源出来的优秀框架,其源码的体系都是极其庞大复杂的,我们不能面面俱到,所以在看源码过程中一定不能被细枝末节缠住,一定要先理清楚整个框架的一个大致思想和大致的框架体系,再去搞那些细枝末节,其效率会好很多,其次在看源码过程中,我们一定要大胆的去想,去猜测,如果这个功能让你自己去写,你会怎么实现!

我们今天学习SpringBean的生命周期也是按照这个8字真言去学习,通过我们之前所学,Spring大致有以下的功能:

  1. 他会帮我们自动的创建对象然后保存起来!
  2. 他会帮我们完成属性的填充!
  3. 如果我们设置了Aop的功能,他会帮我们自动的代理,实现切面功能!

我们从平常的使用中,至少可以得知以上的三点,如果让你自己去实现,必会如何实现呢?

  • 首先他既然能够帮我们自己创建对象,那么他肯定是通过反射来创建的,通过反射来创建,就必定绕不过去要使用Class对象创建,那么我们如何获取Class对象呢? 去扫描项目,将指定的包下的加了注解的类文件切割获取Class名称,通过反射加载Class名称,反射创建java对象!
  • 我们要完成属性的填充,为了方便和性能方面,我肯定会把这些创建好的对象保存起来,无疑Map容器是最合适的!
  • 我们在创建一个对象完成之后,反射拿到里面的属性,如果需要填充,我们先去我们之前保存的容器里面去取,取不出来在反射吧这个依赖的属性创建出来,然后填充进对象再保存在容器里面,从而完成了属性的注入!
  • 填充完成属性之后,我们那当前对象,取与Aop逻辑进行对比,判断是否需要代理,不需要则创建完成,保存进Map容器,需要代理则对当前这个类进行jdk或者cglib的代理然后再保存进容器里面!

于是乎,我们自己实现了一个Spring管理一个Bean的所有过程,画个图,他大概长这样!

自己实现看起来,整个流程就很清晰,扫描、创建、注入、代理、保存一应俱全,但是Spring的实现方式远比我们自己实现的要复杂的多得多!

三、Spring的生命周期流程

Spring作者希望,Spring再着手管理一个Bean的时候,它希望能够让Spring的使用者能够插手,Spring把一个类对象变成一个Java Object的每一步,怎么理解呢?

比如我们买了一栋新房子,这个房子需要取装修,你自己去装修诚然不够专业,不能够面面俱到,所以是我们就找了一个装修公司帮助我们装修新房,于是装修公司就开始预先画好的图纸进行装修,但是在装修的过程中,你为了让自己的新家更加温馨,你想挂一些壁画在墙上,但是图纸上却没有!于是你就找装修公司,要求装修公司在新家的墙上挂上一些壁画!装修公司在接受到你的请求之后,就吩咐装修的工人在图纸之外去给你在墙上挂上壁画之后,然后再接着装修!

上面这个小故事有 这样几个角色,我们把它和Spring对照起来!

  • 你:代表框架的使用者!
  • 新房:代表一个Class文件,你自己也能够装修,但是不够专业,所以交给装修公司! 那么你自己创建对象可能某些使用用起来很麻烦,所以我们交给了Spring容器!
  • 装修公司:代表着Spring容器!
  • 图纸:代表预设步骤,Spring原本就存在的步骤!
  • 工人:Spring提供的各种接口!我们可以通过Spring工厂提供的接口做各种自定义的配置!

上面的小故事,大致可以描述Spring生命周期的核心思想!Spring再对一个Class文件实例化成具体的Spring Bean的时候,它提供了各种接口,由我们自己实现!然后再实例化过程中,不同的时机,去调用不同的接口!从而完成Spring的整个生命周期的创建!

Spring的生命周期大致分为以下部分!

  1. 扫描项目,将项目指定目录下的Class文件转换为Class对象!
  2. 读取Class对象属性包装为BeanDefinition,然后保存再一个Map中!(不难理解,他是为了后续创建或者读取这个类的信息更加方便取而创立的)
  3. 将全部的类转化为BeanDefinition并保存之后,开始调用第一个回调接口BeanFactoryPostProcessor#postProcessBeanFactory()!
  • 它的调用时机是将扫描到的Class文件转换为 BeanDefinition 之后调用的,我们可以通过回调的方法获取所有的BeanDefinition ,而后续的所有对Class的操作都是基于BeanDefinition 操作的,所以,我们可以通过修改它,来改变后续的流程!
  1. 先从当前的容器对象取当前要创建的对象,当取出来的对象为null时开始着手创建对象!
  2. 做一系列的验证,比如验证这个类是否被排除、是否正在创建中、是否有依赖Bean【@DependsOn】注解、是否时单例等等!
  3. 验证通过之后,开始通过反射创建这个对象!
  4. 合并BeanDefinition ,这里涉及到Spring之前版本使用的父子容器的概念,属于另外一个知识点不做讲解!
  5. 判断当前对象是不是单例、是不是支持循环引用、是不是正在创建等!
  6. 执行第二个接口回调InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation()方法!
  • 它的执行时机时实例化完成之后,属性填充之前,它的返回值是一个布尔值,当返回false时,不做自动属性填充!
  1. 执行第三个接口回调InstantiationAwareBeanPostProcessor#postProcessProperties()方法!
  • 他的执行时机是,实例化之后,属性填充检查之后,属性填充之前!它会返回一个属性,后续的属性填充会使用这个方法返回的值!我们可以在这个方法里面修改对应Bean的注入的值!
  1. 填充属性到对象!
  2. 调用第四个回调接口BeanNameAware#setBeanName()方法!
  • 调用时机:属性填充给完毕后,调用初始化方法之前;它的功能是能获取bean的Name!
  1. 调用第五个回调接口BeanClassLoaderAware#setBeanClassLoader()
  • 调用时机:BeanNameAware之后,他的功能是传入bean的类加载器;
  1. 调用第六个回调接口BeanFactoryAware#setBeanFactory()!
  • 调用时机:BeanClassLoaderAware之后,用于设置beanFactory!
  1. 调用第七个回调接口BeanPostProcessor#postProcessBeforeInitialization()方法
  • 调用时机是部分Aware之后,初始化方法之前!传入当前实例化好的对象和beanName,再初始化前做修改!
  1. 回调第八个比较重要的生命周期的初始化方法,它可以是一个InitializingBean接口的bean,也可以是xml中配置的类,也可以是被加了@PostConstruct注解的方法!
  • 该方法内部逻辑可以用户自己编写,调用时机为:实例化完成之后调用!
  1. 回调第九个回调接口BeanPostProcessor#postProcessAfterInitialization()方法!
  • 该方法的调用时机为初始化方法执行之后,这里也是Bean实例化后的最后一步,也是SpringAop实现的重要的一步!
  1. 注册销毁方法,以便Spring容器销毁的时候进行方法的销毁!

整体的方法流程示例图如下:

四、对应源码结构图

相关文章
|
8月前
|
消息中间件 运维 Kafka
|
8月前
|
消息中间件 存储 负载均衡
Kafka【付诸实践 01】生产者发送消息的过程描述及设计+创建生产者并发送消息(同步、异步)+自定义分区器+自定义序列化器+生产者其他属性说明(实例源码粘贴可用)【一篇学会使用Kafka生产者】
【2月更文挑战第21天】Kafka【付诸实践 01】生产者发送消息的过程描述及设计+创建生产者并发送消息(同步、异步)+自定义分区器+自定义序列化器+生产者其他属性说明(实例源码粘贴可用)【一篇学会使用Kafka生产者】
508 4
|
2月前
|
消息中间件 存储 监控
构建高可用性Apache Kafka集群:从理论到实践
【10月更文挑战第24天】随着大数据时代的到来,数据传输与处理的需求日益增长。Apache Kafka作为一个高性能的消息队列服务,因其出色的吞吐量、可扩展性和容错能力而受到广泛欢迎。然而,在构建大规模生产环境下的Kafka集群时,保证其高可用性是至关重要的。本文将从个人实践经验出发,详细介绍如何构建一个高可用性的Kafka集群,包括集群规划、节点配置以及故障恢复机制等方面。
101 4
|
5月前
|
分布式计算 搜索推荐 物联网
大数据及AI典型场景实践问题之通过KafKa+OTS+MaxCompute完成物联网系统技术重构如何解决
大数据及AI典型场景实践问题之通过KafKa+OTS+MaxCompute完成物联网系统技术重构如何解决
|
5月前
|
消息中间件 负载均衡 Kafka
Kafka 实现负载均衡与故障转移:深入分析 Kafka 的架构特点与实践
【8月更文挑战第24天】Apache Kafka是一款专为实时数据处理和流传输设计的高性能消息系统。其核心设计注重高吞吐量、低延迟与可扩展性,并具备出色的容错能力。Kafka采用分布式日志概念,通过数据分区及副本机制确保数据可靠性和持久性。系统包含Producer(消息生产者)、Consumer(消息消费者)和Broker(消息服务器)三大组件。Kafka利用独特的分区机制实现负载均衡,每个Topic可以被划分为多个分区,每个分区可以被复制到多个Broker上,确保数据的高可用性和可靠性。
128 2
|
5月前
|
消息中间件 存储 算法
时间轮在Kafka的实践:技术深度剖析
【8月更文挑战第13天】在分布式消息系统Kafka中,时间轮(Timing Wheel)作为一种高效的时间调度机制,被广泛应用于处理各种延时操作,如延时生产、延时拉取和延时删除等。本文将深入探讨时间轮在Kafka中的实践应用,解析其技术原理、优势及具体实现方式。
168 2
|
5月前
|
消息中间件 安全 Kafka
"深入实践Kafka多线程Consumer:案例分析、实现方式、优缺点及高效数据处理策略"
【8月更文挑战第10天】Apache Kafka是一款高性能的分布式流处理平台,以高吞吐量和可扩展性著称。为提升数据处理效率,常采用多线程消费Kafka数据。本文通过电商订单系统的案例,探讨了多线程Consumer的实现方法及其利弊,并提供示例代码。案例展示了如何通过并行处理加快订单数据的处理速度,确保数据正确性和顺序性的同时最大化资源利用。多线程Consumer有两种主要模式:每线程一个实例和单实例多worker线程。前者简单易行但资源消耗较大;后者虽能解耦消息获取与处理,却增加了系统复杂度。通过合理设计,多线程Consumer能够有效支持高并发数据处理需求。
203 4
|
6月前
|
消息中间件 分布式计算 NoSQL
EMR-Kafka Connect:高效数据迁移的革新实践与应用探索
Kafka Connect是Kafka官方提供的一个可扩展的数据传输框架,它允许用户以声明式的方式在Kafka与其他数据源之间进行数据迁移,无需编写复杂的数据传输代码。
|
8月前
|
消息中间件 SQL Java
阿里云Flink-自定义kafka format实践及踩坑记录(以protobuf为例)
阿里云Flink-自定义kafka format实践及踩坑记录(以protobuf为例)
1410 3
|
8月前
|
消息中间件 网络协议 Kafka
Kafka【付诸实践 02】消费者和消费者群组+创建消费者实例+提交偏移量(自动、手动)+监听分区再平衡+独立的消费者+消费者其他属性说明(实例源码粘贴可用)【一篇学会使用Kafka消费者】
【2月更文挑战第21天】Kafka【付诸实践 02】消费者和消费者群组+创建消费者实例+提交偏移量(自动、手动)+监听分区再平衡+独立的消费者+消费者其他属性说明(实例源码粘贴可用)【一篇学会使用Kafka消费者】
243 3

热门文章

最新文章