Spring的特殊Bean
通过配置后加工Bean,涉及到Bean和Bean工厂的生命周期中;
对Bean进行后处理
spring提供2次机会,让你切入bean的生命周期中,前查或者修改它的配置,这个叫做后处理;
后处理在bean实例化以及装配完成之后发生.
首先,你要实现这个接口
public interface BeanPostProcessor{
Object postProcessBeforeInitialization(Object bean,String name) throws BeansException;
//在bean初始化之前调用
Object postProcessAfterInitialization(Object bean,String name) throws BeansException;
//在初始化后立马调用
}
其次,你要注册实现类
(1)如果系统运行于Bean工厂中,需要调用工厂的addBeanPostProcessor()方法来注册BeanPostProcessor
(2)如果是用应用上下文,像注册其他bean一样注册<bean id="**" class="实现类"/>.容器会自动识别这个bean是一个后处理bean,并在每个bean初始化的时候调用其处理方法;
SPring自己的后处理Bean
ApplicationContextAwareProcessor把应用上下文传递给所有实现了ApplicationContextAware接口的Bean,
不需要自己注册这个后处理bean,应用上下文会自己注册;
DefaultAdvisorAutoProxyCreator自动对系统Bean应用切面.
对Bean工厂进行后处理
BeanFactoryPostProcessor在Bean工厂载入所有的Bean的定义后,实例化Bean之前,对Bean工厂做一些后处理工作.
public interface BeanFactoryPostProcessor{
public void postProcessBeanFactory beanFactory) throws BeansException;
}
Bean工厂容器中不可以使用这种类型的后处理.应用上下文使用时,可以像注册其他bean一样注册;
Spring自己的工厂后处理
PropertyPlaceholderConfigurer,从多个外部属性中载入属性,并且是用这些属性值替换占位符变量;
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceHolderConfigurer">
<property name="location
">//告诉spring从哪里找属性文件
<value>jdbc.properties</value>
</property>
</bean>
CustomEditorConfigurer 注册定制的java.beans.PropertyEditor实现,用它把装配的属性转化为其他类型.
分散配置
如datasource配置
<bean id="propertyConfigurer" class="org.springframwork.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location
">
<value> </value>
</property>
</bean>
or
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer
">
<property name="locations
">
<list>
<value></value>
<value></value>
</list>
</property>
</bean>
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="url"> <value>${**.**}</value></property>
<property name="driverClasName">${**.**} <value></value></property>
<property name="username"> <value>${**.**}</value></property>
<property name="password"> <value>${**.**}</value></property>
</bean>
定制属性编辑器
java.beans.PropertyEditor接口提供了将字符串映射为非String类型的方法;
这个接口的实现java.beans.PropertyEditorSupport,getAsText() 反回表示属性的字符串; setAsText(String value)将传来的字符串赋给Bean属性.
Spring自带几种建立在PropertyEditorSupport之上的定制编辑器,包括org.springframework.beans.propertyeditors.URLEditor,它是一个用于将字符
串与java.net.URL相互转化的编辑器;
自定义编辑器
(1)对要转化的类(ex.Phone),编写编辑器(PhoneEditor);
(2)配置
<bean id="customEditorCnfigurer" class="org.springframework.beans.factory.config.CustomEditorConfigurer">
<property name="customEditors">
<map>
<entry key="Phone_class_name">
<bean id="phoneEditor" class="phone_editor_class_name">
</bean>
</entry>
</map>
</property>
</bean>
(3)使用编辑器
<bean id="contact" class="">
<property name="phoneNumber">
<value>333-333-333</value>
</property>
</bean>
(4)结果.在初始化contact时,会将333-333-333按照定义的editor的方法,转化为Phone类;
解析文本信息
Spring的ApplicationContext通过MessageSource接口为容器提供参数化信息支持;
Spring提供了一个MessageSurce接口的实现 ResourceBundleMessageSource,
它只是调用java自己的java.util.ResourceBundle来解析信息;如果要使用,需添加
<bean id="messageSource
" class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basename">
<value>file_name</value>
</property>
</bean>
messageSource不可以变;
不需要将messageSurce注入到应用系统中的Bean中,而是是用ApplicationContext自己的getMessage()方法;
监听事件
事件都是org.springframework.context.ApplicationEvent的子类;
如果需要Bean对系统事件作出回应,必需实现ApplicationListener接口,
实现onApplicationEvent()方法,这个方法负责处理系统事件;
然后,注册这个Bean <bean id="" class="bean_class"/>
发布事件
首先,创建事件,继承ApplicationEvent;
然后,ApplicationContext有个publishEvent()方法可以发布事件;
感知其他Bean
BeanNameAware(setBeanName),BeanFactoryAware(setBeanFactory)和ApplicationContextAware(setApplictionContext)接口,
可以知道 自己的名字,所处BeanFactory和所处的ApplicationContext.