一丶前言

笔记1和笔记2中我们分析了如何根据xml和注解加载生成BeanDefinition,并注册到BeanFactory,接下载便是Bean的加载,在加载之前会进行一些前置准备

二丶前置准备 和BeanPostProcessor

1.什么是BeanPostProcesser

翻译过来是Bean后置处理器,是Spring留给我们的一个扩展接口,定义了两个方法,会被Spring回调,

调用的时机和大致流程如下图

BeanPostProcesser接口包含如下两个方法

public interface BeanPostProcessor {
//初始化执行之前
Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;
//初始化执行之后
Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;
}

通过BeanPostProcessor我们可以实现自定义对Spring管理的bean进行再加工。比如:可以修改bean的属性,可以给bean生成一个动态代理实例等等。Spring AOP的底层处理也是通过实现BeanPostProcessor来执行代理包装逻辑的。

2.前置准备中的BeanPostProcessor

这里可以看到前置准备给BeanFactory加入了ApplicationContextAwareProcessor和ApplicationListenerDetector,我们详细看下具体操作逻辑

2.1 ApplicationContextAwareProcessor

ApplicationContextAwareProcessor没有在postProcessAfterInitialization中写任何逻辑,但是在postProcessBeforeInitialization 中回执行ApplicationContextAwareProcessor的invokeAwareInterfaces 方法

其实就是如果我们的Bean继承了EnvironmentAware,EmbeddedValueResolverAware,ResourceLoaderAware,ApplicationEventPublisherAware,MessageSourceAware,ApplicationContextAware ,回去调用对应的方法

2.1.1 Aware 接口是什么

Aware接口没有提供任何方法需要实现,只是做一个标记,表示当前这个类,可以被Spring容器执行回调方法,怎么回调呢——ApplicationContextAwareProcessor 就是一个例子

2.2 ApplicationListenerDetector

ApplicationListenerDetector 监听器探测器,非常有意思,使用了一个Map维护Bean的名称和Bean是否单例

2.2.1 维护 singletonNamesMap

2.2.2 销毁Bean之后从多播器中移除

Spring提供的监听器机制,其实是使用一个Set维护了所以的监听器Bean,当Bean销毁后,也就没有必要去在Set维护Bean了,类似于公众号的取关

三.web应用的 postProcessBeanFactory

1.ServletContextAwareProcessor

没什么好看的r,实现了ServletContextAware 和 ServletConfigAware 的接口会通过这个BeanPostProcessor回调setServletContextAware 或者 setServletConfigAware

2.request,session,globalSession 等作用域注册

//注册request,session,globalSession 作用域
WebApplicationContextUtils.registerWebApplicationScopes(beanFactory, this.servletContext);

这些作用域到底是如何实现的,后续看BeanFactory实例化Bean的时候再研究一下

3.注入Web环境的Bean

WebApplicationContextUtils.registerEnvironmentBeans(beanFactory, this.servletContext, this.servletConfig);

主要逻辑是servletContext和 servletConfig的初始化参数 封装成Map注入到BeanFactory

Spring源码学习笔记3——根据BeanDefinition实例化Bean的前置准备的更多相关文章

  1. Spring源码学习笔记之基于ClassPathXmlApplicationContext进行bean标签解析

    bean 标签在spring的配置文件中, 是非常重要的一个标签, 即便现在boot项目比较流行, 但是还是有必要理解bean标签的解析流程,有助于我们进行 基于注解配置, 也知道各个标签的作用,以及 ...

  2. Spring源码学习-容器BeanFactory(四) BeanDefinition的创建-自定义标签的解析.md

    写在前面 上文Spring源码学习-容器BeanFactory(三) BeanDefinition的创建-解析Spring的默认标签对Spring默认标签的解析做了详解,在xml元素的解析中,Spri ...

  3. Spring 源码学习笔记10——Spring AOP

    Spring 源码学习笔记10--Spring AOP 参考书籍<Spring技术内幕>Spring AOP的实现章节 书有点老,但是里面一些概念还是总结比较到位 源码基于Spring-a ...

  4. Spring 源码学习笔记11——Spring事务

    Spring 源码学习笔记11--Spring事务 Spring事务是基于Spring Aop的扩展 AOP的知识参见<Spring 源码学习笔记10--Spring AOP> 图片参考了 ...

  5. Spring源码学习笔记12——总结篇,IOC,Bean的生命周期,三大扩展点

    Spring源码学习笔记12--总结篇,IOC,Bean的生命周期,三大扩展点 参考了Spring 官网文档 https://docs.spring.io/spring-framework/docs/ ...

  6. Spring源码学习-容器BeanFactory(三) BeanDefinition的创建-解析Spring的默认标签

    写在前面 上文Spring源码学习-容器BeanFactory(二) BeanDefinition的创建-解析前BeanDefinition的前置操作中Spring对XML解析后创建了对应的Docum ...

  7. Spring源码学习-容器BeanFactory(二) BeanDefinition的创建-解析前BeanDefinition的前置操作

    写在前面 上文 Spring源码学习-容器BeanFactory(一) BeanDefinition的创建-解析资源文件主要讲Spring容器创建时通过XmlBeanDefinitionReader读 ...

  8. Spring源码学习笔记9——构造器注入及其循环依赖

    Spring源码学习笔记9--构造器注入及其循环依赖 一丶前言 前面我们分析了spring基于字段的和基于set方法注入的原理,但是没有分析第二常用的注入方式(构造器注入)(第一常用字段注入),并且在 ...

  9. Spring源码学习-容器BeanFactory(一) BeanDefinition的创建-解析资源文件

    写在前面 从大四实习至今已一年有余,作为一个程序员,一直没有用心去记录自己工作中遇到的问题,甚是惭愧,打算从今日起开始养成写博客的习惯.作为一名java开发人员,Spring是永远绕不过的话题,它的设 ...

  10. spring源码学习笔记之容器的基本实现(一)

    前言 最近学习了<<Spring源码深度解析>>受益匪浅,本博客是对学习内容的一个总结.分享,方便日后自己复习或与一同学习的小伙伴一起探讨之用. 建议与源码配合使用,效果更嘉, ...

随机推荐

  1. Python3中的printable

    import string characters = string.printable # printable 是用作字符串常量的预初始化字符串.里面包含所有的标点符号,数字 print(charac ...

  2. struct 结构体【GO 基础】

    〇.前言 虽然 Go 语言中没有"类"的概念,也不支持"类"的继承等面向对象的概念,但是可以通过结构体的内嵌,再配合接口,来实现面向对象,甚至具有更高的扩展性和 ...

  3. LAMP配置与应用

    LAMP配置与应用 1.1 动态资源和语言 WEB 资源类型: 静态资源:原始形式与响应内容一致,在客户端浏览器执行 动态资源:原始形式通常为程序文件,需要在服务器端执行之后,将执行结果返回给客户端 ...

  4. 看完包你搞懂Redis缓存穿透、击穿和雪崩!!!说到做到

    缓存穿透 缓存穿透是指当用户对Redis发出无效或者不存在的数据信息操作时,这条数据在Redis中不存在,Redis就会在MySQL数据库中查询,可时无效的信息在mysql数据库中也不存在,就会造成R ...

  5. 浅析KV存储之长尾时延解决办法

    本文分享自华为云社区<浅析KV存储之长尾时延问题,华为云 GeminiDB Redis 探寻行业更优解决方案!>,作者:华为云数据库GaussDB NoSQL团队. 目前,KV存储的广泛使 ...

  6. Python利用pandas进行数据合并

    当使用Python中的pandas库时,merge函数是用于合并(或连接)两个数据框(DataFrame)的重要工具.它类似于SQL中的JOIN操作,允许你根据一个或多个键(key)将两个数据框连接起 ...

  7. 海康单筒红外相机SDK调用方法

    目录 配置环境 1.准备文件 2.配置 3.路径 程序 1.错误警告 2.导入头文件: 3.修改SDK 配置环境 1.准备文件 通过VS创建空白项目后,将海康SDK文件夹: CH-HCNetSDKV6 ...

  8. Sealos 云操作系统私有化部署教程

    Sealos 私有云已经正式发布了,它为企业用云提供了一种革命性的新方案.Sealos 的核心优势在于,它允许企业在自己的机房中一键构建一个功能与 Sealos 公有云完全相同的私有云.这意味着企业可 ...

  9. 【Android】无法通过drawable下的selector类型改变背景颜色?

    举例 我在darwable目录下创建了selector文件,并设置了如下内容 <?xml version="1.0" encoding="utf-8"?& ...

  10. execl表格if函数and和or的使用方法?

    当在Excel中处理数据时,IF函数是非常有用的函数之一.它允许您根据指定的条件执行不同的操作.在IF函数中,AND和OR函数可以帮助您组合多个条件以实现更复杂的逻辑判断.接下来,我将详细描述IF函数 ...