扩展原理 :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,仅供参考)

目录
相关文章
|
3天前
|
运维 Java 程序员
Spring5深入浅出篇:基于注解实现的AOP
# Spring5 AOP 深入理解:注解实现 本文介绍了基于注解的AOP编程步骤,包括原始对象、额外功能、切点和组装切面。步骤1-3旨在构建切面,与传统AOP相似。示例代码展示了如何使用`@Around`定义切面和执行逻辑。配置中,通过`@Aspect`和`@Around`注解定义切点,并在Spring配置中启用AOP自动代理。 进一步讨论了切点复用,避免重复代码以提高代码维护性。通过`@Pointcut`定义通用切点表达式,然后在多个通知中引用。此外,解释了AOP底层实现的两种动态代理方式:JDK动态代理和Cglib字节码增强,默认使用JDK,可通过配置切换到Cglib
|
1天前
|
Java
Springboot 使用自定义注解结合AOP方式校验接口参数
Springboot 使用自定义注解结合AOP方式校验接口参数
Springboot 使用自定义注解结合AOP方式校验接口参数
|
3天前
|
存储 缓存 Java
【JavaEE】Spring中注解的方式去获取Bean对象
【JavaEE】Spring中注解的方式去获取Bean对象
3 0
|
3天前
|
存储 Java 对象存储
【JavaEE】Spring中注解的方式去存储Bean对象
【JavaEE】Spring中注解的方式去存储Bean对象
7 0
|
3天前
|
监控 安全 Java
Spring cloud原理详解
Spring cloud原理详解
18 0
|
3天前
|
JSON 前端开发 Java
【JAVA进阶篇教学】第七篇:Spring中常用注解
【JAVA进阶篇教学】第七篇:Spring中常用注解
|
3天前
|
JavaScript Java 开发者
Spring Boot中的@Lazy注解:概念及实战应用
【4月更文挑战第7天】在Spring Framework中,@Lazy注解是一个非常有用的特性,它允许开发者控制Spring容器的bean初始化时机。本文将详细介绍@Lazy注解的概念,并通过一个实际的例子展示如何在Spring Boot应用中使用它。
21 2
|
3天前
|
前端开发 Java
SpringBoot之自定义注解参数校验
SpringBoot之自定义注解参数校验
19 2
|
3天前
|
Java 开发者 微服务
Spring Cloud原理详解
【5月更文挑战第4天】Spring Cloud是Spring生态系统中的微服务框架,包含配置管理、服务发现、断路器、API网关等工具,简化分布式系统开发。核心组件如Eureka(服务发现)、Config Server(配置中心)、Ribbon(负载均衡)、Hystrix(断路器)、Zuul(API网关)等。本文讨论了Spring Cloud的基本概念、核心组件、常见问题及解决策略,并提供代码示例,帮助开发者更好地理解和实践微服务架构。此外,还涵盖了服务通信方式、安全性、性能优化、自动化部署、服务网格和无服务器架构的融合等话题,揭示了微服务架构的未来趋势。
38 6
|
3天前
|
Java Spring
springboot自带的@Scheduled注解开启定时任务
springboot自带的@Scheduled注解开启定时任务