《Spring2.0 技术手册》读书笔记五-与Spring容器的交互(1)
在前面的例子中,Spring容器在后面管理着Bean实例,我们只需要通过容器门户ApplicationContext或者BeanFactory的getBean()方法来取得实例。但是我们如何使用Spring提供的其他功能呢?如何使用容器中的其他内容呢?即如何与容器交互!
在Bean中获取ApplicationContext/BeanFactory的实例
Bean意识到容器的存在,我们就可以根据自己的需要,取得容器中的资源或使用其他功能,还可以通过容器在某时刻发布事件,让监听此事件的类进行相应处理等。
主要方法是Bean实现Spring中的一些接口:
当然了,还可以实现其他Aware(意识)接口,取得容器中的相关资源,此处不再介绍。实现了Spring中的相关接口,Bean类就会对容器产生依赖,对该类的重用有一定的影响。
Bean事后处理器
通过实现org.springframework.beans.factory.config.BeanPostProcessor接口,在容器对Bean进行初步处理-设置依赖关系后获得控制权,进行相关操作。(postProcessor,事后处理器,这个名字就很恰当的说出了接口的作用)。
BeanPostProcessor接口:
通过BeanPostProcessor将所有Bean的字符串属性值改大写,例子如下:
然后在Bean定义文件中进行配置,让容器知道该类的存在。
BeanFactory事后处理器
在BeanFactory载入Bean定义文件的所有内容,但没正式产生Bean实例前,通过实现org.springframework.beans.factory.config.BeanFactoryPostProcessor接口,可以对BeanFactory进行一些处理。
注:BeanFactory载入定义文件文件,并不是指在加载定义文件是必须使用BeanFactory factory=new XmlBeanFactory(rs)。使用ApplicationContext读取定义文件也是会激发事件的,因为ApplicationContext本身就是一个BeanFactory。它继承的类有:ListableBeanFactory, HierarchicalBeanFactory,
MessageSource, ApplicationEventPublisher, ResourcePatternResolver。
BeanFactoryPostProcessor:
如果某个类实现了该接口,要想容器在加载定义文件后调用此类还要在定义文件中配置该类(<bean id="" class=""/>)。Spring提供了几个实现该接口的类,方便我们使用。举例如下:
PropertyPlaceholderConfigurer
org.framework.beans.factory.config.PropertyPlaceholderConfigurer,可以将一些配置信息移出到一个或多个.properties文件中,即这些配置信息可以不用在xml文件中设置了,xml可以专门负责系统的相关设置,实际应用时的需求可以放在.properties文件里面。
直接在定义文件中定义该类,并设置属性location来指出存放有配置信息的.properties文件位置。
hello.properties文件
那么通过getBean("helloBean")获得的HelloBean实例,它的属性helloWord的值将为PropertyPlaceholderConfigurer Test PropertyOverrideConfigurer
org.framework.beans.factory.config.PropertyOverrideConfigurer,通过此类,可以在.properties文件中设置一些优先的属性,不管xml中某个设置与.properties文件中的某个设置是否重复,该设置值都以.properties文件中的设置为主。
bean定义文件
hello.properties
helloBean实例的属性helloword的值将为PropertyOverrideConfigurer。
CustomEditorConfigurer
org.springframework.beans.factory.config.CustomEditorConfigurer类,可以读取实现java.beans.PropertyEditor接口的类,并按其中的实现,将字符串值转换为指定类型的对象。废话少说,见代码见真理!
Bean定义文件配置CustomEditorConfigurer
用getBean("helloBean")获得的HelloBean实例user属性为正常的User类实例(name=jack,number=123456)。