spring教程
作者:禅楼望月( http://www.cnblogs.com/yaoyinglong )
我们通常使用lookup方法注入,它可使Spring替换一个Bean的抽象或具体方法,返回查找容器中,其他Bean的结果,被查找的Bean通常是一个non-singleton Bean。
无状态的Bean的作用域一般可以配置成singleton单实例,如果我们向singleton的BeanA注入prototype的BeanB,并希望每次调用BeanA的getBeanB()时都能返回一个新的BeanB,使用传统的注入方式方法将无法实现这样的要求。因为singleton的Bean注入关联Bean的动作只有一次,虽然BeanB的作用域是prototype类型,返回的对象不是最开始注入的那个bean。
如果希望每次调用BeanA的getBeanB()时都能返回一个新的BeanB一种可选的方案是让Bean实现BeanFactoryAware接口,让BeanA能访问容器的引用,以下代码可以实现方式达到目的:
[+] view code
public class Bean_A implements BeanFactoryAware{
private Bean_B bean_B= null ;
private BeanFactory beanFactory= null ;
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this .beanFactory=beanFactory;
}
public Bean_B getBean_B(){
return beanFactory.getBean("bean_B", Bean_B. class );
}
}
回忆第一篇里讲的Bean的生命周期,当一个Bean的POJO类实现了BeanFactoryAware接口时,当Bean实例化完成并调用setter方法降属性也设置完毕后,会调用BeanFactoryAware接口的setBeanFactory方法,这样我们便可以得到BeanFactory的一个引用。使用BeanFactory我们便可以获取一个全新的scope= "prototype" 的Bean实例了。
但是,这种方法,使得一个纯净的POJO类被污染了,因此一般情况下不适用这种方法。
1. 使用lookup方法注入
Spring IoC容器有复写Bean方法的能力,这项功能归功于CGLib类包,CGLib可以在运行期动态的操作Class字节码,使Spring替换一个Bean的抽象或具体方法,现在我们将上面的功能使用lookup方法注入来实现:
[+] view code
public class Bean_A{
private Bean_B bean_B= null ;
public Bean_B getBean_B() {
return bean_B;
}
public void setBean_B(Bean_B bean_B) {
this .bean_B = bean_B;
}
}
注意,我们这里的Bean_A是一个纯洁的POJO类。然后在Spring配置文件中为Bean_A添加lookup方法注入,使Spring替换getBean_B() 方法即可。
[+] view code
<bean id= "bean_B" class= "smzq.Bean_B" scope= "prototype" />
<bean id= "bean_A" class= "smzq.Bean_A" >
<lookup-method name = "getBean_B" bean = "bean_B" />
</bean>
测试:
大功告成。
注:lookup方法还可以为bean动态的创建子类或实现类,现在我们声明一个接口,如下:
[+] view code
public interface BeanInterface {
Bean_B getBean_B();
}
同样在Spring的配置文件中配置,但这次配置的不是类,而是一个接口。很神奇吧!
[+] view code
<bean id= "bean_B" class= "smzq.Bean_B" scope= "prototype" />
<bean id= "beanInter" class= "smzq.BeanInterface" >
<lookup-method name = "getBean_B" bean = "bean_B" />
</bean>
再测试一下:
由此可见,Spring确实为我们的BaseInter接口创建了实现类。那么这里是抽象类呢?Spring也会为其创建一个子类。
<lookup-method> 元素只有两个属性:
name:指定要让Spring实现的或者替换的方法名称,该方法返回一个Bean对象。
bean:指定name属性指定的方法的返回值。