学习《spring 3.x企业应用开发实战》之Spring容器高级主题

1、Spring容器技术内幕
1.1、内部工作机制
(1)AbstractApplicationContext
AbstractApplicationContext的refresh()方法定义了spring容器在加载配置文件后的各项处理过程。
//①初始化BeanFactory,在这一步里,spring将配置文件信息装入到容器bean定义的注册表BeanDefinitionRegistry中
ConfigurableListableBeanFactory beanFactory =  this .getBeanFactory();

//②调用工厂后处理器,根据反射机制从BeanDefinitionRegistry中找出所有BeanFactoryPostProcessor类型的Bean,并调用其postProcessBeanFactory接口方法
invokeBeanFactoryPostProcessors(beanFactory)

//③注册Bean后处理器,根据反射机制从BeanDefinitionRegistry中找出所有BeanPostProcessor类型的Bean,并将它们注册到容器Bean后处理器的注册表中
registerBeanPostProcessors(beanFactory)

//④初始化消息源,初始化容器的国际化信息资源
initMessageSource()

//⑤初始化应用上下文事件广播器
initApplicationEventMulticaster()

//⑥初始化其他特殊Bean,由子类具体实现
onRefresh()

//⑦注册事件监听器
registerListeners()

//⑧初始化所有单实例的Bean,懒汉模式的Bean除外
finishBeanFactoryInitialization(beanFactory)

//⑨完成刷新并发布容器刷新事件
finishRefresh()
注:jdk的事件监听器类---------EventObject

(2)IoC的流水线


工厂后处理器主要完成2项工作:
对使用到占位符的<bean/>标签进行解析
对BeanDefinitionRegistery中的BeanDefinition进行扫描,通过java反射机制找出所有属性编辑器的Bean(实现java.beans.PropertyEditor接口的Bean),并自动将它们注册到Spring容器的属性编辑器注册表中(PropertyEditorRegistery)

(3)Spring的高明之处在于,它使用众多接口描绘出了所有装置的蓝图,构建好Spring的骨架,继而通过继承体系层层推演,不断丰富。
所以查看Spring框架的源码时,有2条清晰的脉络:
  • 接口层描述了容器的重要组件及组件间的协作关系;
  • 继承体系逐步实现组件的各项功能。

1.2、BeanDefinition
(1)BeanDefinition是<bean/>元素在容器中的内部表示,BeanDefinition接口的继承结构如图:



①RootBeanDefinition是最常用的实现类,它对应一般性的<bean/>元素,没有子元素的<bean/>就对应RootBeanDefinition。
②BeanDefinition被Spring容器注册到BeanDefinitionRegistry中,BeanDefinitionRegistry就像是Spring配置信息的内存数据库,后续操作直接从BeanDefinitionRegistry中读取配置信息。

(2) 创建最终的BeanDefiniton主要包含2个步骤:
  • 利用BeanDefinitionReader对Resource进行读取;
  • 利用容器中注册的BeanFactoryPostProcessor对半成品BeanDefinition进行加工,以处理占位符的值,


1.3、InstantiationStrategy
(1)Spring之所以将实例化Bean的工作采用策略接口来描述,是为了方便采用不同的实例化策略,如通过cglib类库为Bean动态创建子类再实例化。
InstantiationStrategy的类继承结构如图:



①SimpleInstantiationStrategy是最常用的实现类,该策略利用Bean的构造方法或者工厂方法创建Bnan实例
②CglibSubclassingInstantiationStrategy扩展了SimpleInstantiationStrategy,为需要进行方法注入的Bean提供了支持,它使用cglib为Bean动态生成子类,在子类中实现方法注入的逻辑。

(2)InstantiationStrategy只负责实例化Bean的工作,相当于java中的new功能,它并不会参与Bean属性的设置,属性的设置需要BeanWrapper来完成。

1.4、BeanWrapper
(1)BeanWrapper相当于一个代理器,spring通过BeanWrapper设置Bean的属性值,BeanWrapper类的继承结构如图:



①BeanWrapper有2个顶级接口,分别是PropertyAccessor和PropertyEditorRegistry,
  • PropertyAccessor接口定义了各种访问设置Bean属性的方法;
  • PropertyEditorRegistry是属性编辑器的注册表。
②BeanWrapper的实现类BeanWrapperImpl从BeanDefinitionRegistry获取到BeanDefinition,再从BeanDefinition中获得Bean的属性信息,并利用BeanUtils通过反射对Bean进行操作。

2、属性编辑器
在Spring配置文件里,我们往往通过字面值为Bean的属性设置值,属性编辑器的作用就是将这些字面值转换为相应的double或int型值,所以属性编辑器就是一个类型转换器。

2.1、JavaBean的编辑器
PropertyEditor是JavaBean规范定义的接口。

2.2、Spring默认编辑器
Spring的属性编辑器并非传统的IDE编辑器JavaBean,同时Spring还支持自定义属性编辑器

3、使用外部属性文件
(1)在进行数据源或邮件服务器等资源时,用户可以直接在Spring配置文件中配置用户名、密码。但更好的一种做法是将这些配置信息独立到一个外部属性文件中,并在spring配置文件中通过Spel表达式,形如${xxxx}等占位符引用属性文件中的属性项。
(2)Spring为我们提供了一个PropertyPlaceholderConfigurer,它能够使Bean在配置时引用外部属性文件,PropertyPlaceholderConfigurer实现了
BeanFactoeyPostProcessor接口,所以它也是一个工厂后处理器。xml中配置方式如下:
< bean  class ="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" >
     < property  name ="locations" >
         < list >
             < value > classpath:important.properties </ value >
             < value > classpath:webjsf.properties </ value >
         </ list >
     </ property >
</ bean >
(3)spring提供了一个更优雅的方式,使用
<context:property-placeholder    location="classpath:....................">
(4)在基于注解配置中引用属性
使用@Value("${xxxxx}")引用属性文件中的值。
(5)有时候,用户名、密码等信息需要加密处理,我们可以扩展PropertyPlaceholderConfigurer类,将用户名和密码使用DES加密的密文填入属性文件。并覆盖convertProperty方法,对用户名和密码进行解密转换。
注:使用自定义的解析类时,就无法使用 <context:property-placeholder/>了,必须通过传统的方式,配置PropertyPlaceholderConfigurer的扩展类。
(6)Spring允许在属性文件中使用Spel表达式,实现属性之间的相互引用,如果一个属性值太长写不下,可以通过在航后添加“\”将属性值划分为多行。

4、引用Bean的属性值
spring通过Spel表达式( #{........})在基于注解或者XML的配置中引用其他Bean的属性值

5、容器事件
Spring的ApplicationContext能够发布事件并且允许注册相应的事件监听器,java通过java.util.EventObject类和java.util.EventListener接口描述事件和监听器,某个组件或框架要想建立自己的事件监听机制,一般都通过扩展EventObject和EventListener来实现。
在事件体系中,除了事件和监听器以外,还有另外3个重要的概念:
  • 事件源:事件的产生者,任何一个EventObject都必须有一个事件源;
  • 事件监听器注册表:一个事件监听器注册到组件或者框架中,其实就是保存在监听器注册表里,当组件和框架中的事件源产生事件时,就会将事件通知这些监听器;
  • 事件广播器:它是事件和时间监听器的沟通桥梁,负责把事件通知给事件监听器。

5.1、Spring事件类结构
(1)spring事件类结构如图:



注:ApplicationEvent只有一个构造函数,ApplicationEvent(Object    source),通过source指定事件源。

(2)事件监听器接口类图:



(3)事件广播器类图:



5.2、解构Spring事件体系的具体实现
(1)Spring在ApplicationContext接口的抽象实现类AbstractApplicationContext中完成了事件体系的搭建
AbstractApplicationContext有一个事件广播器applicationEventMulticaster成员变量,该变量提供了容器监听器的注册表。
(2)用户可以自定义事件广播器,如果没有配置自定义广播器,spring将默认使用SimpleApplicationEventMulticaster广播器。
(3)初始化事件广播器之后,spring通过反射机制从BeanDefinitionRegistry中找出所有实现ApplicationListener接口的Bean,将它们添加到事件广播器的监听器注册表中。
(4) 要使自定义的事件广播器拥有发布事件的能力,必须实现ApplicationContextAware接口,ApplicationContextAware接口的publishEvent方法可以发布事件,该方法的参数就是事件。
(5)自定义spring事件监听机制的过程分为3步:
  • 定义一个时间Event;
  • 定义一个监听器Listener;
  • 定义一个事件广播器,实现ApplicationContextAware接口,可以获得ApplicationContext事件源,产生一个事件Event,调用事件源的发布方法publishEvent。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
第1:对Spring框架进行宏观性的概述,力图使读者建立起对Spring整体性的认识。   第2:通过一个简单的例子展现开发Spring Web应用的整体过程,通过这个实例,读者可以快速跨入Spring Web应用的世界。   第3:讲解Spring IoC容器的知识,通过具体的实例详细地讲解IoC概念。同时,对Spring框架的三个最重要的框架级接口进行了剖析,并对Bean的生命周期进行讲解。   第4:讲解如何在Spring配置文件中使用Spring 3.0的Schema格式配置Bean的内容,并对各个配置项的意义进行了深入的说明。   第5:对Spring容器进行解构,从内部探究Spring容器的体系结构和运行流程。此外,我们还将对Spring容器一些高级主题进行深入的阐述。   第6:我们从Spring AOP的底层实现技术入手,一步步深入到Spring AOP的内核中,分析它的底层结构和具体实现。   第7:对如何使用基于AspectJ配置AOP的知识进行了深入的分析,这包括使用XML Schema配置文件、使用注解进行配置等内容。   第8:介绍了Spring所提供的DAO封装层,这包括Spring DAO的异常体系、数据访问模板等内容。   第9:介绍了Spring事务管理的工作机制,通过XML、注解等方式进行事务管理配置,同时还讲解了JTA事务配置知识。   第10:对实际应用中Spring事务管理各种疑难问题进行透彻的剖析,让读者对Spring事务管理不再有云遮雾罩的感觉。   第11:讲解了如何使用Spring JDBC进行数据访问操作,我们还重点讲述了LOB字段处理、主键产生和获取等难点知识。   第12:讲解了如何在Spring中集成Hibernate、myBatis等数据访问框架,同时,读者还将学习到ORM框架的混用和DAO层设计的知识。   第13:本重点对在Spring中如何使用Quartz进行任务调度进行了讲解,同时还涉及了使用JDK Timer和JDK 5.0执行器的知识。   第14:介绍Spring 3.0新增的OXM模块,同时对XML技术进行了整体的了解。   第15:对Spring MVC框架进行详细介绍,对REST风格编程方式进行重点讲解,同时还对Spring 3.0的校验和格式化框架如果和Spring MVC整合进行讲解。   第16:有别于一般书籍的单元测试内容,本书以当前最具实战的JUnit4+Unitils+ Mockito复合测试框架对如何测试数据库、Web的应用进行了深入的讲解。   第17:以一个实际的项目为蓝本,带领读者从项目需求分析、项目设计、代码开发、单元测试直到应用部署经历整个实际项目的整体开发过程。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值