现在的位置: 首页 > 综合 > 正文

8.1.1:Bean后处理器

2013年10月13日 ⁄ 综合 ⁄ 共 3533字 ⁄ 字号 评论关闭

小引:

Spring框架提供了很好的扩展性,除了可以与各种第三方框架良好整合外,其IOC容器也允许开发者进行扩展,这种扩展甚至无须实现BeanFactory或ApplicationContext接口,而是允许通过两个后处理器对IOC容器进行扩展。Spring提供了两种常用的后处理器:

① Bean后处理器:这种后处理器会对容器中的Bean进行后处理,对Bean功能进行额外加强。

② 容器后处理器:这种后处理器对IOC容器进行后处理,用于增强容器功能。

Bean后处理器:

Bean后处理器是一种特殊的Bean,这种特殊Bean并不对外提供服务,它甚至可以无须id属性,它主要负责对容器中的其他Bean执行后处理,例如为容器中的目标Bean生成代理等。

Bean后处理器会在Bean实例创建成功之后,对Bean实例进行进一步的增强处理。

Bean后处理器必须实现 BeanPostProcessor 接口,它包含两个方法:

① Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException:第一个参数是系统即将进行后处理的Bean实例,第二个参数是该Bean实例的名字。

② Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException:第一个参数是系统即将进行后处理的Bean实例,第二个参数是该Bean实例的名字。

实现该接口的Bean后处理器必须实现这两个方法,这两个方法会对容器中的Bean进行后处理,会在目标Bean初始化之前、初始化之后分别被回调,这两个方法用于对容器中的Bean实例进行增强处理。

Axe.java :

public interface Axe {
	public String chop();
}

SteelAxe.java :

public class SteelAxe implements Axe {

	@Override
	public String chop() {
		return "钢斧砍柴真快";
	}

	public SteelAxe() {
		System.out.println("Spring实例化依赖Bean:SteelAxe实例...");
	}
	
	
}

Person.java :

public interface Person {
	public void useAxe();
}

Chinese.java :

public class Chinese implements Person,InitializingBean{
	
	private Axe axe;
	private String name;
	
	public void setAxe(Axe axe) {
		System.out.println("Spring执行依赖关系注入,setAxe...");
		this.axe = axe;
	}

	public void setName(String name) {
		System.out.println("Spring执行依赖关系注入,setName...");
		this.name = name;
	}

	public Chinese() {
		System.out.println("Spring实例化主调Bean:Chinese实例...");
	}

	@Override
	public void useAxe() {
		System.out.println(name+axe.chop());
	}

	@Override
	public void afterPropertiesSet() throws Exception {
		System.out.println("正在执行初始化方法afterPropertiesSet...");
	}

	public void init(){
		System.out.println("正在执行初始化方法init...");
	}
	
}

FirstBeanPostProcessor.java :

public class FirstBeanPostProcessor implements BeanPostProcessor {

	@Override
	public Object postProcessBeforeInitialization(Object bean, String beanName)
			throws BeansException {
		System.out.println("Bean后处理器在初始化之前对"+beanName+"进行增强处理...");
		return bean;
	}

	@Override
	public Object postProcessAfterInitialization(Object bean, String beanName)
			throws BeansException {
		System.out.println("Bean后处理器在初始化之后对"+beanName+"进行增强处理...");
		if(bean instanceof Chinese){
			Chinese c=(Chinese)bean;
			c.setName("中国人");
		}
		return bean;
	}

}

bean.xml核心配置:

 <bean id="chinese" class="com.bean.Chinese" init-method="init">
    <property name="axe" ref="steelAxe"/>
    <property name="name" value="依赖注入的值"/>
 </bean>
  
 <bean id="steelAxe" class="com.bean.SteelAxe"/>
 <bean id="beanPostProcessor" class="com.bean.FirstBeanPostProcessor"/>

Test.java :

public class Test {

	public static void main(String[] args) {
		
		ApplicationContext ctx=new ClassPathXmlApplicationContext("bean.xml");
		Person p=(Person) ctx.getBean("chinese");
		p.useAxe();
	}

}

运行Test.java,控制台输出:

容器中一旦注册了Bean后处理器,Bean后处理器就会自动启动,在容器中每个Bean创建时自动工作。从上面程序的运行结果可以看出,Bean后处理器两个方法的回调时机如下图所示:

采用ApplicationContext作为Spring容器时,无须手动注册BeanPostProcessor。但是如果采用BeanFactory作为Spring容器时,就必须手动注册BeanPostProcess,如下:

public class Test {

	public static void main(String[] args) {
		
		ClassPathResource resource=new ClassPathResource("bean.xml");
		XmlBeanFactory factory=new XmlBeanFactory(resource);
		BeanPostProcessor bpp=(FirstBeanPostProcessor) factory.
                                       getBean("beanPostProcessor");
		factory.addBeanPostProcessor(bpp);  //注册BeanPostProcessor实例
		System.out.println("程序已经实例化BeanFactory...");
		Person p=(Person) factory.getBean("chinese");
		System.out.println("程序中已经完成了chinese bean的实例化...");
		p.useAxe();
	}

}

上面的例子中Bean后处理器没有起到什么实际作用,毕竟这只是个例子。实际工作中Bean后处理器完成的工作更加实际,例如生成Proxy。Spring框架本身提供了大量的Bean后处理器,这些后处理器负责对容器中Bean进行后处理。

下面是Spring提供的两个常用的后处理器:

① BeanNameAutoProxyCreator:根据Bean实例的name属性,创建Bean实例的代理。

② DefaultAdvisorAutoProxyCreator:根据提供的advisor,对容器中所有的Bean实例创建代理。

上面提供的两个Bean后处理器,都用于根据容器中配置的拦截器,创建代理Bean,代理Bean就是对目标Bean进行增强、在目标Bean的基础上进行修改得到新的Bean。

抱歉!评论已关闭.