扩展原理 :Spring注解笔记系列(二)

简介: public interface ApplicationListener<E extends ApplicationEvent> extends EventListener {} -- 如果想要写一个监听器就要实现这个接口,ApplicationEvent就是代表要监听的事件

扩展原理 :Spring注解笔记系列(二)


前一篇讲到 “声明式事务”的环境搭建,如果有兴趣可以步: https://blog.csdn.net/qq_26975307/article/details/89303335


本文企图初窥Spring注解的原理,有兴趣的可以一起探讨,有不对之处敬请指出,一定虚心接受建议并改正。


1、BeanFactoryPostProcessor


(1) BeanPostProcessor:bean后置处理器,bean创建对象初始化前后进行拦截工作


(2) BeanFactoryPostProcessor:BeanFactory后置处理器,在BeanFactory标准初始化之后调用(即所有的Bean定义已被加载,但是还没有Bean被初始化)


(3) IOC创建对象


(4) invokeBeanFactoryPostProcessors(beanFactory);执行BeanFactoryPostProcessor


如何找到所有的BeanFactoryPostProcessor并执行里面的方法?


直接在BeanFactory中找到所有类型是BeanFactoryPostProcessor的组件并执行他们的方法


为什么是在创建对象之后?


执行完finishBeanFactoryInitialization(beanFactory)才初始化剩下的单实例Bean,而在它之前就已经执行了invokeBeanFactoryPostProcessors(beanFactory);


并且是在初始化其他组件之前执行


2、BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor


(1) 所有合法的bean定义将被加载,这些Bean还没有被实例化


(2) 额外定义了一个postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry);


registry定义信息的保存中心,以后Bean工厂就是按照BeanDefinitionRegistry里面保存的每一个Bean定义信息创建bean实例(可以想想:它单例还是多例,实例的类型以及ID是什么)


(3) 优先于BeanFactoryPostProcessor执行,利用BeanDefinitionRegistryPostProcessor再给容器中添加一些额外的组件


(4) BeanDefinitionRegistryPostProcessor原理


1、IOC容器创建


2、refresh().invokeBeanFactoryPostProcessors(beanFactory)


3、先从容器中获取BeanDefinitionRegistryPostProcessor组件

    3.1、触发所有的postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry);

    3.2、再来触发postProcessBeanFactory()方法BeanFactoryPostBeanProcessor;


4、再来从容器中找到BeanFactoryPostpRocessor组件,然后依次触发postProcessBeanFactory()方法


3、ApplicationListener


(1) Spring提供的基于事件驱动开发的功能,监听容器发布的一些事件,完成事件驱动开发


public interface ApplicationListener extends EventListener {} -- 如果想要写一个监听器就要实现这个接口,ApplicationEvent就是代表要监听的事件


(2) 监听步骤


1、写一个监听器(ApplicationEvent实现类)来监听某个事件ApplicationEvent及其子事件

(@EventListener(classes)原理:使用EventListenerMethodprocessor处理器来解析方法上的@EventListener注解)


2、把监听器加入到IOC容器中


3、只要容器中有相关事件发布,就能监听到此事件


3.1、ContextRefreshedEvent:在容器刷新完成(所有bean都完全创建),会发布这个事件


3.2、ContextclosedEvent:关闭容器会触发这个事件


4、发布一个事件:ApplicationEvent.publishEvent();


(3) ApplicationListener原理


1、ContextRefreshedEvent事件


1.1、容器创建对象:refresh()


1.2、容器刷新完成:finishRefresh()会发布ContextRefreshedEvent事件


1.3、publicEvent(new ContextRefreshedEvent(this))


1.3.1、publicEvent事件发布流程


1.3.1.1、获取到事件的多播器(派发器):getApplicationEventMulticaster()---将事件派发给多个监听器,让它们同时监听


1.3.1.2、派发事件:multicaster()


1.3.1.3、获取到所有的

ApplicationListener(  for(final ApplicationListener listener : getApplicationLisers(evnt,type))  )


如果有Excutor,可以支持使用Excutor进行异步派发;否则同步的方式直接执行拦截的Lintener方法:invokeListener(listener,event)---拿到Listener回调onApplicationEvent方法


2、自己发布事件


3、容器关闭会发布ContextClosedEvent事件


4、事件多播器是如何拿到的?


4.1、IOC容器在创建对象的时候,要进行refresh()


4.2、refresh()会调用非常多的方法,其中就有一个名为initApplicationEventMulticaster()--在完成其他bean创建之前就先初始化


4.2.1、先去容器中找有没有id="applicationEventMulticaster"    的组件如果没有则this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);然后再注册到容器当中,就可以在其他组件要派发事件的时候自动注入applicationEventMulticaster


5、容器中有哪些监听器?


5.1、因为容器在创建对象时候需要刷新,在刷新的时候有一步

registerListener(); String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);


5.2、从容器中拿到所有的监听器,将他们注册到applicationMulticater中

getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);


5.3、如果找到了组件,将监听器加入到容器中了,所以容器中就会判断哪些组件是实现了ApplicationListner接口的


(4) SmartInitialization原理


1、afterSingletonsInstantiated() --当单实例Bean全部创建完成之后执行,类似于容器刷新完成


2、IOC容器创建对象并刷新容器


3、finishBeanFactoryInitialization(beanFactory)--初始化剩下的单实例Bean


3.1、先创建所有的单实例Bean(一个for循环拿到所有需要创建的Bean,通过getBean的方法获得Bean)


3.2、所有的单实例Bean创建完以后,再一个for循环,把所有的Bean拿到从创建好的Bean中获取Bean对象,判断是否是SmartInitialization接口类型的,如果是则调用afterSingletonsInstantiated()


由于重装系统后代码不慎丢失,如需参考,找回后我将上传github,仅供参考)

目录
相关文章
|
2月前
|
缓存 监控 Java
SpringBoot @Scheduled 注解详解
使用`@Scheduled`注解实现方法周期性执行,支持固定间隔、延迟或Cron表达式触发,基于Spring Task,适用于日志清理、数据同步等定时任务场景。需启用`@EnableScheduling`,注意线程阻塞与分布式重复问题,推荐结合`@Async`异步处理,提升任务调度效率。
523 128
|
2月前
|
人工智能 Java 开发者
【Spring】原理解析:Spring Boot 自动配置
Spring Boot通过“约定优于配置”的设计理念,自动检测项目依赖并根据这些依赖自动装配相应的Bean,从而解放开发者从繁琐的配置工作中解脱出来,专注于业务逻辑实现。
|
1月前
|
XML Java 测试技术
《深入理解Spring》:IoC容器核心原理与实战
Spring IoC通过控制反转与依赖注入实现对象间的解耦,由容器统一管理Bean的生命周期与依赖关系。支持XML、注解和Java配置三种方式,结合作用域、条件化配置与循环依赖处理等机制,提升应用的可维护性与可测试性,是现代Java开发的核心基石。
|
1月前
|
XML Java 应用服务中间件
【SpringBoot(一)】Spring的认知、容器功能讲解与自动装配原理的入门,带你熟悉Springboot中基本的注解使用
SpringBoot专栏开篇第一章,讲述认识SpringBoot、Bean容器功能的讲解、自动装配原理的入门,还有其他常用的Springboot注解!如果想要了解SpringBoot,那么就进来看看吧!
366 2
|
2月前
|
XML Java 数据格式
常用SpringBoot注解汇总与用法说明
这些注解的使用和组合是Spring Boot快速开发和微服务实现的基础,通过它们,可以有效地指导Spring容器进行类发现、自动装配、配置、代理和管理等核心功能。开发者应当根据项目实际需求,运用这些注解来优化代码结构和服务逻辑。
293 12
|
2月前
|
Java 测试技术 数据库
使用Spring的@Retryable注解进行自动重试
在现代软件开发中,容错性和弹性至关重要。Spring框架提供的`@Retryable`注解为处理瞬时故障提供了一种声明式、可配置的重试机制,使开发者能够以简洁的方式增强应用的自我恢复能力。本文深入解析了`@Retryable`的使用方法及其参数配置,并结合`@Recover`实现失败回退策略,帮助构建更健壮、可靠的应用程序。
353 1
使用Spring的@Retryable注解进行自动重试
|
2月前
|
传感器 Java 数据库
探索Spring Boot的@Conditional注解的上下文配置
Spring Boot 的 `@Conditional` 注解可根据不同条件动态控制 Bean 的加载,提升应用的灵活性与可配置性。本文深入解析其用法与优势,并结合实例展示如何通过自定义条件类实现环境适配的智能配置。
183 0
探索Spring Boot的@Conditional注解的上下文配置
|
2月前
|
智能设计 Java 测试技术
Spring中最大化@Lazy注解,实现资源高效利用
本文深入探讨了 Spring 框架中的 `@Lazy` 注解,介绍了其在资源管理和性能优化中的作用。通过延迟初始化 Bean,`@Lazy` 可显著提升应用启动速度,合理利用系统资源,并增强对 Bean 生命周期的控制。文章还分析了 `@Lazy` 的工作机制、使用场景、最佳实践以及常见陷阱与解决方案,帮助开发者更高效地构建可扩展、高性能的 Spring 应用程序。
130 0
Spring中最大化@Lazy注解,实现资源高效利用
|
2月前
|
Java 测试技术 编译器
@GrpcService使用注解在 Spring Boot 中开始使用 gRPC
本文介绍了如何在Spring Boot应用中集成gRPC框架,使用`@GrpcService`注解实现高效、可扩展的服务间通信。内容涵盖gRPC与Protocol Buffers的原理、环境配置、服务定义与实现、测试方法等,帮助开发者快速构建高性能的微服务系统。
558 0
|
Java API Spring
Spring容器如何使用一个注解来指定一个类型为配置类型
Spring容器如何使用一个注解来指定一个类型为配置类型
192 0