spring源码-扩展点
/**
* @Author quan
* @Date 2020/11/13
* 扩展原理
* BeanPostProcessor bean后置处理器,bean创建对象初始化前后进行拦截工作
*
*
* BeanFactoryPostProcessor BeanFactory后置处理器
* 在BeanFactory标准初始化之后调用,所有的Bean定义已经保存加载到BeanFactory,可以修改订制BeanFactory的内容
* 但是BeanFactory还没帮我们实例化
*
* 1ioc容器创建对象
* 2invokeBeanFactoryPostProcessors(beanFactory)执行BeanFactoryPostProcessor
* 如何拿到所有BeanFactoryPostProcessors 在这个类PostProcessorRegistrationDelegate(invoker入口AbstractApplicationContext)
* String[] postProcessorNames =
* beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
* 这里取获取所有后置bean的name,然后进行排序
* 1.直接在BeanFactory中找到所有类型是BeanFactoryPostProcessor的组件,并执行他们的方法
* 2.在初始化创建其他组件前执行
*
*
* BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor
* void postProcessBeanDefinitionRegistry
* 指定世纪:看源码注解iiu知道了。在所有Bean定义信息将要被加载的时候,bean实例还未创建的时候
* 比BeanFactoryPostProcessor还要前,
* 利用BeanDefinitionRegistryPostProcessor给容器中添加额外添加一些组件
*
* 原理:
* 1ioc容器创建
* 2refresh()->invokeBeanFactoryPostProcessors(beanFactory);
* 3从容器中获取到所有的BeanDefinitionRegistryPostProcessor AbstractApplicationContext#invokeBeanFactoryPostProcessors实际上执行:PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors
* 4依次触发所有的postProcessBeanDefinitionRegistry invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
* 5再触发:postProcessBeanFactory实际上是再BeanFactoryPostProcessor
* 6再从容器中找到BeanFactoryPostProcessor组件,返回一次触发postProcessBeanFactory。
*
*
* ApplicationListener:监听容器中发布的时间,事件驱动模型开发
* public interface ApplicationListener<E extends ApplicationEvent> extends EventListener
* 都要监听ApplicationEvent及其下面的子事件:
* 步骤:
* 1下一个监听器来监听某个事件(ApplicationEvent及其子类)
* 2监听器加入到容器
* 3只要容器中有相关事件的发布,我们九年监听到这个事件。
* Spring发布的事件 ContextRefreshedEvent 容器刷新完成(所有Bean都被完全创建),会发布这个事件
* ContextClosedEvent 关闭容器会发布这个事件
* 4发布一个事件:
* applicationContext.publishEvent();
*
* 原理:
* 第一个事件:ContextRefreshedEvent
* 1容器创建 refresh()
* 2finishRefresh容器刷新完成
* 这个方法里面调用了 publishEvent(new ContextRefreshedEvent(this))
* 里面发布流程:
* 1-获取事件的多播器()getApplicationEventMulticaster()
* 2-multicastEvent派发事件
* 3-获取所有的ApplicationListener
* for (ApplicationListener<?> listener : getApplicationListeners(event, type)) {
* 1-如果有Executor 可以支持使用Executor进行异步派发
* Executor executor = getTaskExecutor();
* 2-否则同步执行invokeListener(listener, event);
* 3-拿到Listener回调onApplicationEvent方法listener.onApplicationEvent(event)
* 最后一个事件:ContextCloseEvent
* AbstractApplicationContext#doClose();
*
*
* {事件多播器怎么获取的呢}:
* 1.容器创建对象Refresh:
* 2.AbstractApplicationContext#initApplicationEventMulticaster();初始化事件多播器
* 1-先去BeanFactory里面有没有id=applicationEventMulticaster的Bean
* 2-如果没有就新建一个new SimpleApplicationEventMulticaster(beanFactory),并注册进去:
* beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
* 那就可以再其他组件要派发事件,则自动注入即可
*
* {容器有那些监听器}
* 1.容器创建对象Refresh:
* 2.registerListeners();
* 从容器中拿到所有的监听器,
* String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
* 把他们注册到ApplicationEventMulticaster中
* getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
*
* #另一种是心啊监听器的方法@EventListener
* 原理:
* 1-点进注解里面,看注释可以直到主要工作的市EventListenerMethodProcessor来解析注解
*
* SmartInitializingSingleton原理:---》执行时机afterSingletonsInstantiated
* 1-ioc容器创建对象并refresh
* 2-finishBeanFactoryInitialization 初始化剩下的单实例bean
* 1-其实执行的市DefaultListableBeanFactory#preInstantiateSingletons
* 2-先创建所有的单实例bean,getBean
* 3-获取所有创建好的单实例bean,判断是否是SmartInitializingSingleton类型
* 并执行smartSingleton.afterSingletonsInstantiated();
*/
/**
* @Author quan
* @Date 2020/11/13
* 扩展点=-BeanFactoryPostProcessor
* <p>
* <p>
* * Modify the application context's internal bean factory after its standard
* * initialization. All bean definitions will have been loaded, but no beans
* * will have been instantiated yet. This allows for overriding or adding
* * properties even to eager-initializing beans.
* * @param beanFactory the bean factory used by the application context
* * @throws org.springframework.beans.BeansException in case of errors
*/ @Component
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
// System.out.println(" MyBeanFactoryPostProcessor");
int count = beanFactory.getBeanDefinitionCount();
System.out.println("MyBeanFactoryPostProcessor"+count);
String[] names = beanFactory.getBeanDefinitionNames();
System.out.println(Arrays.asList(names));
}
}
/**
* @Author quan
* @Date 2020/11/13
*/
@Component
public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor { //BeanDefinitionRegistry Bean定义信息的保存中心
//BeanFactory都是按照BeanDefinitionRegistry里面保存的每一个Bean定义信息创建Bean的实例
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
System.out.println("MyBeanDefinitionRegistryPostProcessor-postProcessBeanDefinitionRegistry数量" +registry.getBeanDefinitionCount());
// RootBeanDefinition beanDefinition = new RootBeanDefinition(Quan.class);
AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(Quan.class).getBeanDefinition();
registry.registerBeanDefinition("quan",beanDefinition);
} @Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("MyBeanDefinitionRegistryPostProcessor-postProcessBeanFactory数量" +beanFactory.getBeanDefinitionCount());
}
}
/**
* @Author quan
* @Date 2020/11/20
*/
@Service
public class MyServiceEventListener { @EventListener(classes = {ApplicationEvent.class})
public void listen(ApplicationEvent event){
System.out.println("EventListener"+event);
}
}
/**
* @Author quan
* @Date 2020/11/18
*/
@Component//需要加载到容器中去
public class MyApplicationListener implements ApplicationListener<ApplicationEvent> {
//当容器发布此事件的时候,方法会得到促发
@Override
public void onApplicationEvent(ApplicationEvent event) {
System.out.println("事件-----"+event);
}
}
spring源码-扩展点的更多相关文章
- Spring源码系列 — BeanDefinition扩展点
前言 前文介绍了Spring Bean的生命周期,也算是XML IOC系列的完结.但是Spring的博大精深,还有很多盲点需要摸索.整合前面的系列文章,从Resource到BeanDefinition ...
- Spring源码学习笔记12——总结篇,IOC,Bean的生命周期,三大扩展点
Spring源码学习笔记12--总结篇,IOC,Bean的生命周期,三大扩展点 参考了Spring 官网文档 https://docs.spring.io/spring-framework/docs/ ...
- 【Spring源码分析】Bean加载流程概览
代码入口 之前写文章都会啰啰嗦嗦一大堆再开始,进入[Spring源码分析]这个板块就直接切入正题了. 很多朋友可能想看Spring源码,但是不知道应当如何入手去看,这个可以理解:Java开发者通常从事 ...
- 【Spring源码分析】非懒加载的单例Bean初始化前后的一些操作
前言 之前两篇文章[Spring源码分析]非懒加载的单例Bean初始化过程(上篇)和[Spring源码分析]非懒加载的单例Bean初始化过程(下篇)比较详细地分析了非懒加载的单例Bean的初始化过程, ...
- 框架源码系列六:Spring源码学习之Spring IOC源码学习
Spring 源码学习过程: 一.搞明白IOC能做什么,是怎么做的 1. 搞明白IOC能做什么? IOC是用为用户创建.管理实例对象的.用户需要实例对象时只需要向IOC容器获取就行了,不用自己去创建 ...
- spring源码分析系列 (5) spring BeanFactoryPostProcessor拓展类PropertyPlaceholderConfigurer、PropertySourcesPlaceholderConfigurer解析
更多文章点击--spring源码分析系列 主要分析内容: 1.拓展类简述: 拓展类使用demo和自定义替换符号 2.继承图UML解析和源码分析 (源码基于spring 5.1.3.RELEASE分析) ...
- 【Spring源码分析】Bean加载流程概览(转)
转载自:https://www.cnblogs.com/xrq730/p/6285358.html 代码入口 之前写文章都会啰啰嗦嗦一大堆再开始,进入[Spring源码分析]这个板块就直接切入正题了. ...
- Ioc容器beanDefinition-Spring 源码系列(1)
Ioc容器beanDefinition-Spring 源码系列(1) 目录: Ioc容器beanDefinition-Spring 源码(1) Ioc容器依赖注入-Spring 源码(2) Ioc容器 ...
- Spring源码分析:非懒加载的单例Bean初始化前后的一些操作
之前两篇文章Spring源码分析:非懒加载的单例Bean初始化过程(上)和Spring源码分析:非懒加载的单例Bean初始化过程(下)比较详细地分析了非懒加载的单例Bean的初始化过程,整个流程始于A ...
随机推荐
- Asp.net core IdentityServer4与传统基于角色的权限系统的集成
写在前面 因为最近在忙别的,好久没水文了 今天来水一篇: 在学习或者做权限系统技术选型的过程中,经常有朋友有这样的疑问 : "IdentityServer4的能不能做到与传统基于角色的权限系 ...
- [Python]小白入门时遇到的各种问题
Q:关于Python2.X和Python3.X各种版本有什么区别,小白应该选哪个? A: 1.背景及简要介绍 Python 2 发布于 2000 年年底. 随着 Python 2 的不断发展,更多的功 ...
- 『无为则无心』Python基础 — 61、Python中的迭代器
目录 1.迭代的概念 2.迭代器的概念 3.可迭代的对象(Iterable) 4.迭代器对象(Iterator) 5.迭代器的使用体验 (1)基本用法 (2)实际应用 1.迭代的概念 (1)什么是迭代 ...
- 2021年国内外五大BI厂商_商业智能工具推荐
每家公司对于BI工具的使用都有自己的特点和期望,所以当面对国内外那么多的BI厂商时,大家可能会觉得难以选择.今天我将会为大家介绍国内外五大BI厂商,对于它们做出一些分析,让大家更了解这些BI厂商. ...
- C语言字符串输入输出函数(gets()函数、puts()函数、fgets()函数、fputs()函数)
scanf("%s", str) 不能读取空白字符,遇到第一个空白字符就停止读取. gets(str) 读取整行输入,直至遇到换行符,丢弃换行符储存其余字符,并在末尾添加 \0.与 ...
- 【C# 集合】Hash哈希函数 |散列函数|摘要算法
希函数定义 哈希函数(英語:Hash function)又称散列函数.散列函数.摘要算法.单向散列函数.散列函数把消息或数据压缩成摘要,使得数据量变小,将数据的格式固定下来.该函数将数据打乱混合,重新 ...
- Python:Scrapy(一) 基础知识与实例
学习自: Scrapy爬虫框架教程(一)-- Scrapy入门 - 知乎 Scrapy爬虫框架,入门案例(非常详细)_ck784101777的博客-CSDN博客_scrapy爬虫案例 爬虫框架Scra ...
- 如何建立自己的代理IP池,减少爬虫被封的几率
如何建立自己的代理IP池,减少爬虫被封的几率 在爬虫过程中,难免会遇到各种各样的反爬虫,运气不好,还会被对方网站给封了自己的IP,就访问不了对方的网站,爬虫也就凉凉. 代理参数-proxies 首先我 ...
- Python 完美诠释"高内聚"概念的 IO 流 API 体系结构
1. 前言 第一次接触 Python 语言的 IO API 时,是惊艳的.相比较其它语言所提供的 IO 流 API . 无论是站在使用者的角度还是站在底层设计者的角度,都可以称得上无与伦比. 很多人在 ...
- @PostConstruct使用注意点
前景提要:在一个项目中,由于数据库中敏感词删除掉了,但是在网页进行匹配时仍然能够匹配上已删除的词. 查看项目源码发现使用了@PostConstruct注解: 此注解的作用是:@PostConstruc ...