扩展原理 :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 开发者 Spring
【SpringBoot 异步魔法】@Async 注解:揭秘 SpringBoot 中异步方法的终极奥秘!
【8月更文挑战第25天】异步编程对于提升软件应用的性能至关重要,尤其是在高并发环境下。Spring Boot 通过 `@Async` 注解简化了异步方法的实现。本文详细介绍了 `@Async` 的基本用法及配置步骤,并提供了示例代码展示如何在 Spring Boot 项目中创建与管理异步任务,包括自定义线程池、使用 `CompletableFuture` 处理结果及异常情况,帮助开发者更好地理解和运用这一关键特性。
125 1
|
2月前
|
缓存 Java 数据库连接
Spring Boot奇迹时刻:@PostConstruct注解如何成为应用初始化的关键先生?
【8月更文挑战第29天】作为一名Java开发工程师,我一直对Spring Boot的便捷性和灵活性着迷。本文将深入探讨@PostConstruct注解在Spring Boot中的应用场景,展示其在资源加载、数据初始化及第三方库初始化等方面的作用。
56 0
|
1天前
|
Java Spring 容器
Spring IOC、AOP与事务管理底层原理及源码解析
Spring框架以其强大的控制反转(IOC)和面向切面编程(AOP)功能,成为Java企业级开发中的首选框架。本文将深入探讨Spring IOC和AOP的底层原理,并通过源码解析来揭示其实现机制。同时,我们还将探讨Spring事务管理的核心原理,并给出相应的源码示例。
18 9
|
2天前
|
缓存 NoSQL Java
Springboot自定义注解+aop实现redis自动清除缓存功能
通过上述步骤,我们不仅实现了一个高度灵活的缓存管理机制,还保证了代码的整洁与可维护性。自定义注解与AOP的结合,让缓存清除逻辑与业务逻辑分离,便于未来的扩展和修改。这种设计模式非常适合需要频繁更新缓存的应用场景,大大提高了开发效率和系统的响应速度。
10 2
|
11天前
|
Java Spring 容器
Spring使用异步注解@Async正确姿势
Spring使用异步注解@Async正确姿势,异步任务,spring boot
|
10天前
|
XML Java 数据格式
spring复习03,注解配置管理bean
Spring框架中使用注解配置管理bean的方法,包括常用注解的标识组件、扫描组件、基于注解的自动装配以及使用注解后的注意事项,并提供了一个基于注解自动装配的完整示例。
spring复习03,注解配置管理bean
|
11天前
|
XML 前端开发 Java
控制spring框架注解介绍
控制spring框架注解介绍
|
24天前
|
Java 数据库连接 API
【Java笔记+踩坑】Spring Data JPA
从常用注解、实体类和各层编写方法入手,详细介绍JPA框架在增删改查等方面的基本用法,以及填充用户名日期、分页查询等高级用法。
【Java笔记+踩坑】Spring Data JPA
|
24天前
|
Java 数据库连接 数据格式
【Java笔记+踩坑】Spring基础2——IOC,DI注解开发、整合Mybatis,Junit
IOC/DI配置管理DruidDataSource和properties、核心容器的创建、获取bean的方式、spring注解开发、注解开发管理第三方bean、Spring整合Mybatis和Junit
【Java笔记+踩坑】Spring基础2——IOC,DI注解开发、整合Mybatis,Junit
|
2月前
|
监控 安全 Java
【开发者必备】Spring Boot中自定义注解与处理器的神奇魔力:一键解锁代码新高度!
【8月更文挑战第29天】本文介绍如何在Spring Boot中利用自定义注解与处理器增强应用功能。通过定义如`@CustomProcessor`注解并结合`BeanPostProcessor`实现特定逻辑处理,如业务逻辑封装、配置管理及元数据分析等,从而提升代码整洁度与可维护性。文章详细展示了从注解定义、处理器编写到实际应用的具体步骤,并提供了实战案例,帮助开发者更好地理解和运用这一强大特性,以实现代码的高效组织与优化。
57 0
下一篇
无影云桌面