背景
深入理解Spring容器的工作底层
1.内部工作机制
Spring的AbstractApplicationContext是ApplicationContext的抽象实现类,该抽象类的refresh()方法定义了
Spring容器在加载配置文件后的各项处理过程。refresh()内部定义如下:
Spring容器从加载配置文件到创建出一个完整Bean的作业流程及参与的角色:
在看Spring框架源码时,有两条清晰的脉络:接口层描述了容器的重要组成及组件间的协作关系;继承体
系逐步实现组件的各项功能。
Spring组件按其所承担的角色可以划分为两类:(1)物料组件,如Resource、BeanDefinition、PropertyEditor和
Bean,他们是加工流程中被加工、被消费的组件,就像流水线的被加工的物料一样;(2)设备组件,如ResourceLoader、
BeanDefinitionReader、BeanFactoryPostProcessor、InstantiationStrategy及BeanWrapper等,他们就像流水
线上不同环节的加工设备、对物料组件进行加工处理。
2.BeanDefinition
3.InstantiationStrategy
SimpleInstantialtionStrategy利用Bean实现类的默认构造器、带参构造函数或工厂方法创建Bean的实例;
CglibSubclassingInstantiationStrategy为需要进行方法注入的Bean提供了支持。它利用CGLib类库为Bean
动态生成子类,在子类中生成方法注入的逻辑,然后使用这个动态生成的子类创建Bean的实例。
4.BeanWrapper
PropertyAccessor接口定义了各种访问Bean属性的方法;PropertyEditorRegistry是属性编辑器的注册表。
5.属性编辑器
任何实现java.beans.PropertyEditor接口的类都是属性编辑器。主要的功能就是将外部的设置值转换为JVM
内部对应类型。
自定义属性编辑器,需要覆盖PropertyEditorSupport的setAsText()方法
6.使用外部属性文件
在进行数据源或邮件服务器等资源的配置时,可以将配置信息独立到一个外部属性文件中,在Spring配置文件中
通过${user}、${password}的占位符引用属性文件中的属性项。
(1)PropertyPlaceholderConfigurer属性文件
(2)使用<context:property-placeholder>引用属性文件
(3)基于注解及java类的配置中引用属性,利用@Value注解
(4)使用加密的属性文件,可以覆盖convertProperties、convertProperty、convertPerpertyValue方法,对属性值进
行转换。
信息的加密可分为对称和非对称两种方式,前者表示加密后的信息可以解密成原值,而后者不能根据加密后的信息
还原为原值。MD5属于非对称加密,DES属于对称加密。
(5)属性文件自身的引用,可以通过${xxx}来实现属性间的相互引用
7.引用Bean的属性值
可以通过#{xxx.xxx}的方式引用Bean的属性值。
在基于注解和基于java类配置的Bean中,可以通过@Value("#{xxx.xxx}")的注解形式引用Bean的属性值。
8.国际化信息
(1)要开发支持多国语言的Web应用程序,需要为每种语言提供一套相应的资源文件,并以规范化命名的方式保存在特
定的目录中,由系统自动根据客户端语言选择合适的资源文件。
使用“语言类型”和“国家/地区类型”来确定一个特定类型的本地化信息,两个条件缺一不可。
Java通过java.util.Locale类表示一个本地化对象,允许通过语言参数和国家/地区参数创建一个确定的本地化对象。
JDK的java.util包中提供了几个支持本地化的格式化操作工具类,如NumberFormat、DataFormat和MessageFormat。
国际化资源文件的命名规范规定资源名称采用以下方式进行命名:<资源名>_<语言代码>_<国家/地区代码>.properties
<资源名>.properties命名的国际化资源文件是默认的资源文件。
<资源名>_<语言代码>.properties命名的国家化资源文件是某一语言默认的资源文件。
JDK在bin目录下提供了native2ascii工具,将中文字符的资源文件转换位Unicode编码格式的文件。
可以通过ResourceBoundle加载本地化资源文件。
(2)MessageSource:
ReloadableResourceBundleMessageSource可以定时刷新资源文件。
(3)容器级的国际化信息资源,在Spring容器启动时,步骤4的initMessageSource()方法所执行的工作就是
初始化容器的国际化信息资源。 容器级资源的配置:
9.容器事件
java.util.EventObject类和java.util.EvenListener类接口描述了事件和监听器。
在事件体系中,还有另外三个重要的概念:
(1)事件源:事件的产生者
(2)事件监听器注册表:一个事件监听器注册到组件或框架中,其实就是保存在事件监听器注册表中。
(3)事件广播器:它是事件和事件监听器沟通的桥梁,负责把事件通知给事件监听器。
Spring事件类结构:
(1)事件类
(2)事件监听器接口
GenericApplicationListener增强了对泛型事件类型的支持,ResolvableType是Spring4.0提供的一个更加
简单易用的泛型操作支持类。
(3)事件广播器
AbstractApplicationContext在refresh()这个容器启动方法中通过以下3个步骤搭建了事件的基础设施:
ApplicationEventMulticaster提供了容器监听器的注册表。
总结
这里只是记录了一些大概的内容,不是很详细的记录,有关内容得到书里面去看。