IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> Spring源码深度解析 容器的功能扩展总结 -> 正文阅读

[Java知识库]Spring源码深度解析 容器的功能扩展总结

ApplicationContext 和 BeanFacotry 两者都是用于加载 Bean 的,但是相比之下, ApplicationContext
提供了更多的扩展功能,简单一点说 ApplicationContext 包含 BeanFactory 的所有功能
通常建议比 BeanFactory 优先 ,除非在一些限制的场合,比如字节长度对内存有很大的影响时
(Applet)
使用 BeanFactory 方式加载 XML
在这里插入图片描述
使用 ApplicationContext 方式加载 XML
在这里插入图片描述

在这里插入图片描述
ClassPathXmlApplicationContext 中可以将配置文件路径以数
组的方式传人, ClassPathXmlApplicationContext 可以对数组进行解析并进行加载 而对于解析及功能实现都在 refresh()中实现

设置配置路径
在这里插入图片描述
此函数主要用于解析给定的路径数组,当然, 如果数组中包含特殊符号,如${var},那么
在resolvePath中会搜寻匹配的系统变量并替换

扩展功能
设置了路径之后,便可以根据路径做配置文件的解析以及各种功能的实现了
在这里插入图片描述
在这里插入图片描述
ClassPathXm!ApplicationContext 初始化的步骤
初始化前的准备工作,例如对系统属性或者环境变量进行准备及验证
初始化 BeanFactory 并进行 XML 文件读取
对BeanFactory 进行各种功能填充
子类覆盖方法做额外的处理
激活各种 BeanFactory 处理器
注册拦截 bean 创建的 bean 处理器,这里只是注册, 真正的调用是在 getBean 时候
为上下文初始化 Message 源,即对不同语言的消息体进行国际化处理
初始化应用消息广播器,并放入“applicationEventMulticaster” bean中
留给子类来初始化其他的 bean
在所有注册的 bean 中查找 listenerbean 注册到消息广播器中
初始化剩下的单实例(非惰性的)
完成刷新过程,通知生命周期处理器 lifecycleProcessor 刷新过程,同时发出 ContextRefreshEvent
通知别人

环境准备
prepareRefresh 函数主要是做些准备工作,例如对系统属性及环境变量的初始化及验证
在这里插入图片描述
initPropertySources 正符合 Spring 的开放式结构设计,给用户最大扩展 Spring 的能力
用户可以根据自身的需要重写 initPropertySources 方法,并在方法中进行个性化的属性处理及
设置
validateRequiredProperties 则是对属性进行验证
假如现在有这样一个需求,工程在运行过程中用到的某个设置(例如 VAR )是从系统环境
变量中取得的,而如果用户没有在系统环境变量中配置这个参数,那么工程可能不会工作 这
一要求可能会有各种各样的解决办法 当然,在Spring中可以这样做,可以直接修改 Spring
的源码,例如修改 ClassPathXmlApplicationContext 当然,最好的办法还是对源码进行扩展
可以自定义类:
在这里插入图片描述
还需要在使用的时候替换掉原有的ClassPathXmlApplicationContext
在这里插入图片描述

加载 BeanFactory
obtainFreshBeanFactory 正是实现 BeanFactory 的地方
在这里插入图片描述
在这里插入图片描述
方法中将核心实现委托给了refreshBeanFactory:
在这里插入图片描述
创建DefaultListableBeanFactory
指定序列化 ID
定制BeanFactory
加载BeanDefinition
使用全局变量记录 BeanFactory 类实例

定制 BeanFactory
这里已经开始了对 BeanFactory 的扩展,在基本容器的基础上,增加了是否允许覆盖是否
允许扩展的设置并提供了注解@Qualifier 和@Autowired 的支持
在这里插入图片描述
对于允许覆盖和允许依赖的设置这里只是判断了是否为空,如果不为空要进行设置
在这里插入图片描述
解析 autowire 类型时首先会调用方法
在这里插入图片描述
在 QualifierAnnotationAutowireCandidateResolver 中一定会提供了解析
Qualifier 与 Autowire 注解的方法
在这里插入图片描述

加载 BeanDefinition
在实现配置文件的加载功能中除了我们在第一步中已经初始化的 DefaultListableBeanFactory 外,
还需要 XmlBeanDefinitionReader 来读取 XML
在这里插入图片描述
在初始化了 DefaultListableBeanFactory 和 XmlBeanDefinitionReader 后就可以进行配置文件
的读取了
在这里插入图片描述

功能扩展
在这里插入图片描述
在这里插入图片描述
上面函数中主要进行了几个方面的扩展
增加对 SpEL 语言的支持
增加对属性编辑器的支持
增加对一些内直类,比如 EnvironmentAware MessageSourceAware 的信息注入
设直了依赖功能可忽略的接口
注册一些固定依赖的属性
增加 Aspect 的支持
将相关环境变量及属性注册以单例模式注册

增加 SpEL 语言的支持
Spring 表达式语言全称为 Spring Expression Language ,缩写为 SpEL ,类似于 Struts 2x 中使
用的 OGNL 表达式语言 ,能在运行时构建复杂表达式、存取对象图属性、对象方法调用等,并
且能与 Spring 功能完美整合 ,比如能用来配置 bean 定义 SpEL 是单独模块,只依赖于 core
模块 不依赖于其他模块,可以单独使用
SpEL 使用#{ ...}作为定界符,所有在大框号中的字符都将被认为是 SpEL ,使用格式如下:
在这里插入图片描述
一般通过 AbstractBeanFactory 中的 evaluateBeanDefinitionString
方法去完成 SpEL 的解析
在这里插入图片描述

增加属性注册编辑器
在Spring DI 注入的时候可以把普通属性注入进来,但是像 Date 类型就无法被识别
在这里插入图片描述
上面代码中 需要对日期型属性进行注入:
在这里插入图片描述
在这里插入图片描述
如果直接这样使用,程序则会报异常, 类型转换不成功

Spring 针对此问题提供了两种解决办法
使用自定义属性编辑器
使用自定义属性编辑器,通过继承 PropertyEditorSupport ,重写 setAsText 方法,
在这里插入图片描述
在这里插入图片描述

注册 Spring 自带的属性编辑器 CustomDateEditaor
在这里插入图片描述

ResourceEditorRegistrar 的内部实现
在这里插入图片描述
在这里插入图片描述

ResourceEditorRegistrar 的 registerCustomEditors 方法的调用层次结构
在这里插入图片描述

AbstractBeanFactory 中的 registerCustomEditors 方法的调用层次结构
在这里插入图片描述
在 bean的初始化后会调用 ResourceEditorRegistrar 的 registerCustomEditors 方法进行批量的通用属性编
辑器注册 注册后,在属性填充的环节便可以直接让 Spring 使用这些编辑器进行属性的解析了

BeanWrapperlmpl 除了实现 BeanWrapper 接口外
还继承了 PropertyEditorRegistrySupport
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

添加 ApplicationContextAwareProcessor处理器
对于 postProcessAfterlnitialization 方法,在 ApplicationContextAwareProcessor 中并没有做过
多逻辑处理
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

设置忽略依赖
在这里插入图片描述

注册依赖
在这里插入图片描述

Beanfactory 的后处理

激活注册的 BeanFactoryPostProcessor

BeanFactoryPostProcessor 的典型应用: PropertyPlaceholderConfigurer
在这里插入图片描述
变量引用: ${ bean.message } 这就是 Spring 的分散配置 ,可以在另外的配
置文件中为 bean.message 指定值 如在 bean.property 配置如下定义
在这里插入图片描述
当访问名为 message 的 bean 时, mes 属性就会被置为字符串 “ Hi,can you find me?”
在这里插入图片描述

使用自定义 BeanFactoryPostProcessor
在这里插入图片描述
在这里插入图片描述
通过 ObscenityRemovingBeanFactoryPostProcessor Spring 很好地实现了屏蔽掉 obscenties定
义的不应该展示的属性

激活 BeanFactoryPostProcessor
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

对于 BeanDefinitionRegistry 类型的处理类的处理主要包括以下内容
对于硬编码注册的后处理器的处理 ,主要是通过 AbstractApplicationContext 中的添加处
理器方法 addBeanFactoryPostProcessor 进行添加
在这里插入图片描述
记录后处理器主要使用了3个List完成
registryPostProcessors 记录通过硬编码方式注册的 BeanDefinitionRegistryPostProcessor
类型的处理器
regularPostProcessors :记录通过硬编码方式注册的 BeanFactoryPostProcessor 类型的处
理器
registryPostProcessorBeans 记录通过配置方式注册的BeanDefinitionRegistryPostProcessor
类型的处理器
对以上所记录的 List 中的后处理器进行统一调用 BeanFactoryPostProcessor的
postProcessBeanFactory 方法
对beanFactoryPostProcessors 中非 BeanDefinitionRegis PostProcessor 型的 理器进行
BeanFactoryPostProcessor 的 postProcessBeanFactory 方法调用
普通beanFactory处理

注册BeanPostProcessor
Spring 中大部分功能都是通过后处理器的方式进行扩展的 这是 Spring 框架的一个特性 但是在 BeanFactory 中其实并没有
实现后处理器的自动注册 所以在调用的时候如果没有进行手动注册其实是不能使用的 但是
在ApplicationContext 中却添加了自动注册功能
在这里插入图片描述
在这里插入图片描述
那么使用 BeanFactory 方式进行 Spring 的 bean 的加载时是不会有任何改变的,但是使用
ApplicationContext 方式获取 bean 的时候会在获取每个 bean 时打印出 “===”,而这个特性就
是在 registerBeanPostProcessors 方法中完成的
在这里插入图片描述
在这里插入图片描述

对于 internalPostProcessors 中存储的后处理器也就是
MergedBeanDefinitionPostProcessor 类型的处理器,在代码中似乎是被重复调用了
在这里插入图片描述
其实不是
在这里插入图片描述

初始化消息资源
java.util.Locale 是表示语言和国家/地区信息的本地化类 ,它是创建国际化应用的基础
在这里插入图片描述
JDK 的 java.util 包中 提供了几个支持本地化的格式化操作工具类 NumberFormat
DateFormat MessageFormat
在这里插入图片描述

HierarchicalMessageSource 接口的几个实现类,
在这里插入图片描述

ResourceBundleMessageSource 的实现方式
在这里插入图片描述
在这里插入图片描述

在initMessageSource 中获取自定义资源文件的方式为 beanFactory.getBean(MESSAGE_
SOURCE BEAN NAME, MessageSource.class),在这里 Spring 使用了硬编码的方式硬性规定了
子定义资源文件必须为 message ,否则便会获取不到自定义资源配置,这也是为什么之前提到
Bean 的 id 如果部位 message 会抛出异常
在这里插入图片描述
在这里插入图片描述

在 AbstractApplicationContext 中的获取资源文件属性的方法
在这里插入图片描述
其中的 getMessageSource() 方法正是获取了之前定义的自定义资源配置

初始化 ApplicationEventMulticaster
在这里插入图片描述
在这里插入图片描述

ApplicationEventMulticaster 是如何被初始化的
initApplicationEve ntMulticaster 的方式比较简单 ,无非考虑两种情况
如果用户自定义了事件广播器 ,那么使用用户自定义的事件广播器
如果用户没有自定义事件广播器,那么使用默认的 ApplicationEventMulticaster
在这里插入图片描述

默认的广播器实现 SimpleApplicationEventMulticaster
在这里插入图片描述

注册监听器
在这里插入图片描述

初始化非延迟加载单例
在这里插入图片描述

ConversionService 的设置
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

冻结配置
冻结所有的 bean 定义,说明注册的 bean 定义将不被修改或进行任何进一步的处理
在这里插入图片描述

初始化非延迟加载
ApplicationContext 实现的默认行为就是在启动时将所有单例 bean 提前进行实例化 提
前实例化意味着作为初始化过程的一部分 ApplicationContext 实例会创建并配置所有的单例
bean 而这个实例化的过程就是在 finishBeanFactorylnitialization 中完成的
在这里插入图片描述
在这里插入图片描述

finishRefresh
在 Spring 中还提供了 Lifecycle 接口, Lifecycle 中包含 start/stop 方法,实现此接口后 Spring 会
保证在启动的时候调用其 start 方法开始生命周期,并在 Spring 关闭的时候调用 stop 方法来结束生
命周期,通常用来配置后台程序,在启动后一直运行(如对 MQ 进行轮询等)而 ApplicationContext
的初始化最后正是保证了这一功能的实现
在这里插入图片描述
在这里插入图片描述

initlifecycleProcessor
当ApplicationContext 启动或停止时,它会通过 LiifecycleProcessor 来与所有声明的 bean 的
周期做状态更新,而在 LifecycleProcessor 的使用前首先需要初始化
在这里插入图片描述

onRefresh
启动所有实现了 Lifecycle 接口的 bean
在这里插入图片描述
在这里插入图片描述
publishEvent
当完成 ApplicationContext 初始化的时候,要通过 Spring 中的事件发布机制来发出 ContextRefreshedEvent 事件,以保证对应的监听器可以做进一步的逻辑处理
在这里插入图片描述

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-03-15 22:18:55  更:2022-03-15 22:20:15 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 9:52:23-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码