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