0%

ApplicationContext原理

[toc]

ApplicationContext除了拥有 BeanFactory支持的所有功能之外,还进一步扩展了基本容器的功能,包括
BeanFactoryPostProcessor、
BeanPostProcessor
其他特殊类型bean的自动识别
容器启动后bean实例的自动初始化
国际化的信息支持
容器内事件发布等


3种ApplicationContext的实现
FileSystemXmlApplicationContext :从文件系统加载bean
ClassPathXmlApplicationContext :从Classpath加载bean
XmlWebApplicationContext :用于Web应用程序的ApplicationContext实现


新特性一:统一资源加载策略#

Spring提出了一套基于Resource和ResourceLoader接口的资源抽象和加载策略。

  • ByteArrayResource 将字节(byte)数组提供的数据作为一种资源进行封装? ClassPathResource 从Java应用程序的ClassPath中加载具体资源并进行封装
  • FileSystemResource 以文件或者URL的形 式对该类型资源进行访问,只要能跟File打的交道
  • UrlResource 通过java.net.URL进行的具体资源查找定位的实现类,内部委派URL进行具 体的资源操作。
  • InputStreamResource 较为少用。

ResourceLoader:查找和定位这些资源,资源定位器
在这里插入图片描述
相关资源的ResourceLoader实现类:

  • DefaultResourceLoader
    在这里插入图片描述

  • FileSystemResourceLoader
    在这里插入图片描述

  • ResourcePatternResolver(ResourceLoade的子接口)
    是1个批量查找的ResourceLoader,会返回resource数组 实
    可以根据指定的资源路径匹配模式, 每次返回多个Resource实例
    支持基 于Ant风格的路径匹配模式(类似于**/.suffix之类的路径形式),支持ResourcePatternResolver新 增加的classpath:前缀等

总关系图
在这里插入图片描述
ApplicationContextt默认继承了ResourcePatternResolver,间接实现了ResourceLoader接口
任何的ApplicationContext实现都可以看作是一个 ResourceLoader甚至ResourcePatternResolver

  • ApplicationContext的资源用法:
    1.扮演ResourceLoader的角色
    在这里插入图片描述

2.ResourceLoader类型的注入
ApplicationContext类型容器可以自动识别Aware接口
因此会自动把自己注入到需要ResourceLoader的实例中
在这里插入图片描述

3.Resource类型的注入
BeanFactory如果想注入Resource类型的bean定义,就需要注册自定义的PropertyEditor到 BeanFactory容器
而Application- Context容器可以正确识别Resource类型并转换后注入相关对象
在这里插入图片描述

  1. 在特定情况下,ApplicationContext的Resource加载行为

Spring扩展了协议前缀的集合。
ResourceLoader中增加了一种新 的资源路径协议——classpath:,
ResourcePatternResolver又增加了一种——classpath*:。
classpath*:与classpath:的唯一区别就在于,如果能够在classpath中找到多个指定的资源,则 返回多个

ClassPathXmlApplicationContext默认从classpath中加载bean定义配置文件
在这里插入图片描述

FileSystemXmlApplicationContext默认尝试从文件系统中加载bean定义文件
在这里插入图片描述

但通过加前缀file或者classpath,可以修改加载方式

新增特性二:国际化信息支持#

1.Java SE 提供的国际化支持:
不同的 Locale代表不同的国家和地区,每个国家和地区在Locale这里都有相应的简写代码表ResourceBundle用来保存特定于某个Locale的信息
通过结合ResourceBundle和Locale,我们就能够实现应用程序的国际化信息支持

Spring在Java SE的国际化支持的基础上,进一步抽象了国际化信息的访问接口,也就是 MessageSource
在这里插入图片描述

ApplicationContext还 实现了MessageSource接口,
3种MessageSource实现
StaticMessageSource 。可以通过编程的方式添加信息条目,多用于测试,不应该用于正式的生产环境。
ResourceBundleMessage 是常用的、用于正式生产环境
ReloadableResourceBundleMessageSource 定期刷新并检查底层的properties资源文件是否有变更。

ApplicationContext 启动的时候,会自动识别容器中类型为MessageSourceAware的bean定义
并将自身作为MessageSource注入相应对象实例中
PS:看一下自己工程里怎么实现的

新增特性三:容器内部事件发布#

java自带事件发布:
在这里插入图片描述
ApplicationContext 容器内部允许以ApplicationEvent的形式发布事件,。
容器内注册的ApplicationListener类型的bean定义会被ApplicationContext容器自动识别
一旦容器内发布ApplicationEvent及其子类型的事件, 注册到容器的ApplicationListener就会对这些事件进行处理。

application自定义事件ApplicationEvent
Spring提供了三个实现。

  • ContextClosedEvent:ApplicationContext容器在即将关闭的时候发布的事件类型。
  • ContextRefreshedEvent:ApplicationContext容器在初始化或者刷新的时候发布的事件类 型。
  • RequestHandledEvent:Web请求处理后发布的事件,其有一子类ServletRequestHandled- Event提供特定于Java EE的Servlet相关事件。

application自定义监听器ApplicationListener
在启动时,会自动识别并加载EventListener类型bean定义, 一旦容器内有事件发布,将通知这些注册到容器的EventListener

application自定义发布者ApplicationContext
ApplicationContext接口定义还继承了ApplicationEventPublisher接口

容器启动伊始,就会检查容器内是否存在名称为ApplicationEventMulticaster的 ApplicationEventMulticaster对象实例。
有的话就使用提供的实现,没有则默认初始化一个 SimpleApplicationEventMulticaster作为将会使用的ApplicationEventMulticaster
在这里插入图片描述

Spring的ApplicationContext容器内的事件发布机制,主要用于单一容器内的简单消息通知和处 理,并不适合分布式、多进程、多容器之间的事件通知
发布步骤:
1.MethodExecutionEvent的改装
在这里插入图片描述

2.MethodExecutionEventListener的改
在这里插入图片描述

3.MethodExeuctionEventPublisher改造
在这里插入图片描述

  1. 注册到ApplicationContext容器
    在这里插入图片描述

特性四:多配置模块加载的简化
在这里插入图片描述