Spring框架学习笔记-方法注入

1.singleton与prototype作用域

<bean id="person1"  class="com.bean.life.Person">
    <property name="name">
        <value>小明</value>
    </property>
</bean>
<bean id="person2"  class="com.bean.life.Person">
    <property name="name">
        <value>小红</value>
    </property>
</bean>

刚接触spring两天,之前一直对这两个概念有误解,一直以为 singleton 说的是所有实现“同名class”的bean指向的是同一个java实例,以上面的bean为例,之前一直认为 person1、person2 是对同一 com.bean.life.Person 对象的引用,so foolish ,不论bean的作用域定位为 singleton 还是 prototype ,person1、person2 都是不同的实例 !
正解是:xml 中配置的每一个 bean 都是不同的实例 !
singleton 指的是 single bean,每个 bean 都只有一个实例对象,不论调用多少次 getBean()方法,不论有多少 ref 依赖,spring 容器中都只有一个 bean 实例。
prototype 指的是都针对这个 bean ,每当调用 getBean()方法,或是有 ref 依赖时,都会创建一个全新的 bean 实例,容器中有多个 bean 实例
注:Spring 中的缺省作用域是: Singleton 。
无状态Bean的作用域一般可以配置为singleton单实例模式,如果我们往singleton的Boss中注入prototype的Car,并希望每次调用Boss Bean的getCar()时都能返回一个新的Car Bean,使用传统的注入方法将无法实现这样的要求。因为singleton的Bean注入关联Bean的动作仅发生一次,虽然Car Bean的作用范围是prototype类型,但Boss通过getCar()返回对象还是最开始的那个CarBean。
如果希望每次调用getCar()都返回一个新的Car Bean的实例,我们该怎么做呢?

2.lookup方法注入-通过一个singleton Bean获取一个prototype Bean时使用

我们先定义一个MagicBoss接口,并声明一个getCar()方法:

package com.baobaotao.injectfun;
public interface MagicBoss{
	Car getCar();
}

下面我们不编写任何实现类,仅通过配置为该接口提供动态的实现,让getCar()接口方法每次都返回新的CarBean:

<bean id="car" class="com.baobaotao.injectfun.Car" p:brand="红旗CA72" p:price="2000" scope="prototype"/>
<bean id="magicBoss" class="com.baobaotao.injectfun.MagicBoss">
	<lookup-method name="getCar" bean="car"/>
</bean>

通过lookup-method元素标签为MagicBoss的getCar()提供动态实现,返回prototype的car Bean,这样Spring将在运行期为MagicBoss接口提供动态实现,其效果等同于:

package com.baobaotao.injectfun;
public class MagicBosslmpl implements MagicBoss,ApplicationContextAware{
	private ApplicationContext ctx;
	public Car getCar(){
		return (Car)ctx.getBean("car");//从容器中获取car Bean.
	}
	public void setApplicationContext(ApplicationContext ctx)throws BeansException{
		this.ctx=ctx;
	}
}

因为每次调用MagicBoss的getCar()方法,都从容器中获取car Bean,由于car Bean的作用域是prototype,所以每次返回的都是新的car实例。
如果将car Bean的作用域设置为singleton,虽然以上的配置照常可以运行,但这时,lookup所提供的方法注入就没有什么意义了。因为我们容易编写一个MagicBoss接口实现类,用属性注入的方式达到相同的目的。所以lookup方法注入是有一定使用范围的,一般就是希望通过一个singleton Bean获取一个prototype Bean时使用

3.方法替换

在Spring IoC容器中,是否有办法可以使用某个Bean的方法去替换另一个Bean的方法呢?
在下面的例子中,Boss1的getCar()方法,返回一辆宝马Z4:

package com.baobaotao.injectfun;
public class Boss1{
	public Car getCar(){
		Car car=new Car();
		car.setBrand("宝马Z4");
		return car;
	}
}

Boss2实现了Spring的org.springframework.beans.factory.support.MethodReplacer接口:

package com.baobaotao.injectfun;
import java.lang.reflect.Method;
import org.springframework.beans.factory.support.MethodReplacer;
public class Boss2 implements MethodReplacer{
	public Object reimplement(Object arg0,Method arg1,Objectp[] arg2){
		Car car=new Car();
		car.setBrand("奥迪A8L");
		return car;
	}
}

用于替换他人的Bean必须实现MethodReplacer接口,Spring将利用该接口方法去替换目标Bean的方法。下面,我们将通过Spring IoC容器的”乾坤大挪移“术,用Boss2的方法去替换Boss1的getCar():

<bean id="boss1" class="com.baobaotao.injectfun.Boss1">
	<replaced-method name="getCar" replacer="boss2"/>
</bean>
<bean id="boss2" class="com.baobaotao.injectfun.Boss2"/>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值