小引:
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。
本文深入探讨了Spring框架中的Bean后处理器机制,包括Bean后处理器和容器后处理器的概念、实现方式及应用实例,详细解释了它们如何对IOC容器进行扩展与增强。
1521

被折叠的 条评论
为什么被折叠?



