8 -- 深入使用Spring -- 1...1Bean后处理器
8.1.1 Bean后处理器(BeanPostProcessor)
Bean后处理器主要负责对容器中其他Bean执行后处理,例如为容器中的目标Bean生成代理等。
Bean后处理器会在Bean实例创建成功之后,对Bean实例进行进一步的增强处理。
Bean后处理器必须实现BeanPostProcessor接口,BeanPostProcessor接口包含如下两个方法:
⊙ Object postProcessBeforInitialization(Object Bean,String name) throws BeanException : 该方法的第一个参数是系统即将进行后处理的Bean实例,第二个参数是该Bean的配置id。在目标Bean初始化之前被回调。
⊙ Object postProcessAfterInitialization(Object Bean,String name) throws BeanException : 该方法的第一个参数是系统即将进行后处理的Bean实例,第二个参数是该Bean的配置id。在目标Bean初始化之后被回调。
Demo-----------------
Class : Chinese
package edu.pri.lime._8_1_1.bean.impl; import org.springframework.beans.factory.InitializingBean; import edu.pri.lime._8_1_1.bean.Axe; import edu.pri.lime._8_1_1.bean.Person; public class Chinese implements Person,InitializingBean{ private String name; private Axe axe; public Chinese() { super(); System.out.println("1.Spring 实例化主调Bean:Chinese实例。。。"); } public String getName() { return name; } public void setName(String name) { System.out.println("2.Spring 执行setName() 方法注入依赖关系。。。"); this.name = name; } public Axe getAxe() { return axe; } public void setAxe(Axe axe) { System.out.println("2.Spring 执行setAxe() 方法注入依赖关系。。。"); this.axe = axe; } public void afterPropertiesSet() throws Exception { System.out.println("4.1生命周期方法。。。"); } public void init(){ System.out.println("4.2生命周期方法。。。"); } public void useAxe() { System.out.println(name + axe.chop()); } }
Class : MyBeanPostProcessor
package edu.pri.lime._8_1_1; import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanPostProcessor; import edu.pri.lime._8_1_1.bean.impl.Chinese; public class MyBeanPostProcessor implements BeanPostProcessor { /** * 对容器中Bean实例进行后处理 * @param bean 需要进行后处理的原Bean实例 * @param beanName 需要进行后处理的Bean的配置id * @return 返回后处理完成或测Bean */ public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { System.out.println("3.Bean 后处理器在初始化之前对" + beanName + "进行增强处理。。。"); //返回的处理或的Bean实例,该实例就是容器中实际使用的Bean return bean; } public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { System.out.println("5.Bean 后处理器在初始化之后对" + beanName + "进行增强处理。。。"); if(bean instanceof Chinese){ Chinese chinese = (Chinese)bean; chinese.setName("Oracle"); } return bean; } }
XML :
<?xml version="1.0" encoding="UTF-8"?> <!-- Spring 配置文件的根元素,使用Spring-beans-4.0.xsd语义约束 --> <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd"> <bean id="chinese" class="edu.pri.lime._8_1_1.bean.impl.Chinese" init-method="init"> <property name="name" value="lime"/> <property name="axe" ref="steelAxe"/> </bean> <bean id="steelAxe" class="edu.pri.lime._8_1_1.bean.impl.SteelAxe"/> <!-- 配置Bean后处理器,可以无须指定id属性 --> <bean class="edu.pri.lime._8_1_1.MyBeanPostProcessor"/> </beans>
Class : BeanPostProcessorMain
package edu.pri.lime._8_1_1.bean.main; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import edu.pri.lime._8_1_1.bean.Person; import edu.pri.lime._8_1_1.bean.impl.Chinese; public class BeanPostProcessorMain { public static void main(String[] args){ ApplicationContext ctx = new ClassPathXmlApplicationContext("app_8_1_1.xml"); Person person = ctx.getBean("chinese",Chinese.class); person.useAxe(); } }
Console :
1.Spring 实例化主调Bean:Chinese实例。。。 3.Bean 后处理器在初始化之前对steelAxe进行增强处理。。。 5.Bean 后处理器在初始化之后对steelAxe进行增强处理。。。 2.Spring 执行setName() 方法注入依赖关系。。。 2.Spring 执行setAxe() 方法注入依赖关系。。。 3.Bean 后处理器在初始化之前对chinese进行增强处理。。。 4.1生命周期方法。。。 4.2生命周期方法。。。 5.Bean 后处理器在初始化之后对chinese进行增强处理。。。 2.Spring 执行setName() 方法注入依赖关系。。。 Oracle使用钢斧砍材真快
如果使用ApplicationContext作为Spring容器,Spring容器会自动检测容器中的所有Bean,如果发现某个Bean类实现了BeanPostProcessor接口,ApplicationContext 会自动将其注册为Bean后处理器。
Bean后处理器两个方法的回调时机:
如果使用BeanFactory作为Spring容器,则必须手动注册Bean后处理器,程序必须获取Bean后处理器实例,然后手动注册,这就需要在配置文件中为Bean处理器指定id属性。
Resource isr = new ClassPathResource("app_8_1_1.xml"); DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); new XmlBeanDefinitionReader(beanFactory).loadBeanDefinitions(isr); // 获取容器中的Bean后处理器 BeanPostProcessor bp = (BeanPostProcessor)beanFactory.getBean("bp"); // 注册Bean后处理器 beanFactory.addBeanPostProcessor(bp); Person per = (Person) beanFactory.getBean("chinese"); per.useAxe();
啦啦啦