本文中主要包含:
23.使用后台处理器post-processor
1.使用BeanPostProcessor
如果向一个bean factory注册post-processor的话,那么对于这个工厂产生的每个bean的实例的话,都会调用Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException和Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException方法。这里需要注意的是ApplicationContext会自动检测并注册post-processor,但是BeanFactory需要手动注册。使用方法如下:
MyBeanPostProcessor.java:
/** * */ package beanfactory.postprocessor; import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanPostProcessor; import beanfactory.SimpleBean; /** * @author jefferyxu * */ public class MyBeanPostProcessor implements BeanPostProcessor { /* (non-Javadoc) * @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessAfterInitialization(java.lang.Object, java.lang.String) */ @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { ((SimpleBean)bean).setMsg("i am called by the postProcessAfterInitialization."); return bean; } /* (non-Javadoc) * @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessBeforeInitialization(java.lang.Object, java.lang.String) */ @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { ((SimpleBean)bean).setMsg("i am called by the postProcessBeforeInitialization"); return bean; } }
客户端程序:
Resource resource = new ClassPathResource("applicationContext.xml"); ConfigurableBeanFactory context = new XmlBeanFactory(resource); BeanPostProcessor postProcessor = new MyBeanPostProcessor(); context.addBeanPostProcessor(postProcessor); SimpleBean simpleBean = (SimpleBean)context.getBean("simpleBean"); System.out.println(simpleBean.getMsg());
2.使用BeanFactoryPostProcessor定制bean工厂
如果一个类实现上面的接口,那么这个类就能在bean factory创建之后,完成对于这个bean factory的修改。spring中包含很多现成的实现上面接口的实现类:PropertyPlaceholderConfigurer,PropertyOverrideConfigurer。下面是这两个的实例。
1.PropertyPlaceholderConfigurer
如果在applicationContext.xml文件中定义:
<bean id="myDataSource" class="beanfactory.postprocessor.MyDataSource" abstract="false" lazy-init="default" autowire="default" p:username="${jdbc.username}" p:dirverClassName="${jdbc.driverClassName}" p:pasword="${jdbc.password}" p:url="${jdbc.url}"> </bean>
同时存在下面的文件jdbc.properties:
jdbc.driverClassName=myDriverName jdbc.username=jefferyxu jdbc.password=password jdbc.url=url
客户端:
package beanfactory.postprocessor; import org.springframework.beans.factory.config.ConfigurableBeanFactory; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer; import org.springframework.beans.factory.config.PropertyResourceConfigurer; import org.springframework.beans.factory.xml.XmlBeanFactory; import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.Resource; public class BeanFactoryPropPlaceHolderUsage { public static void main(String[] args) { Resource resource = new ClassPathResource("applicationContext.xml"); ConfigurableBeanFactory context = new XmlBeanFactory(resource); // 根据配置文件生成PropertyResourceConfigurer PropertyResourceConfigurer propertyResourceConfigurer = new PropertyPlaceholderConfigurer() ; resource = new ClassPathResource("jdbc.properties"); propertyResourceConfigurer.setLocation(resource); // 执行真正的替换 propertyResourceConfigurer.postProcessBeanFactory((ConfigurableListableBeanFactory) context); // 去得配置之后的datasource MyDataSource dataSource = (MyDataSource)context.getBean("myDataSource"); System.out.println(dataSource.getDirverClassName()); } }