Spring3之 bean Method injection

本文介绍了Spring框架中的方法注入(Method Injection)与方法替换(Method Replacement)两种高级依赖注入技术。通过实例展示了如何使用lookup-method解决singleton bean调用prototype bean的问题,并通过方法替换实现特定方法的功能增强。

Method injection(方法注入

bean都是singleton类型的。如果一个singleton bean要引用另外一个singleton bean,或者一个非singleton bean要引用另外一个非singleton bean时,通常情况下将一个bean定义为另一个bean的property值就可以了。不过对于具有不同生命周期的bean来说这样做就会有问题了,比如在调用一个singleton类型bean A的某个方法时,需要引用另一个非singleton(prototype)类型的bean B,对于bean A来说,容器只会创建一次,这样就没法在需要的时候每次让容器为bean A提供一个新的的bean B实例。

官方建议:You can make bean A aware of the container by implementing the ApplicationContextAware interface, and by making a getBean("B") call to the container ask for (a typically new) bean B instance every time bean A needs it.

http://blog.youkuaiyun.com/zml2004/archive/2006/04/15/664309.aspx例子

Lookup Method Injection 

 

 

<!--EndFragment-->

com.spring305.test.methodInjection.RandomT.java

public class RandomT{

    private int num = (int)(100*Math.random());
    public void printRandom(){
        System.out.println("随机数是"+num);
    }
}

 

com.spring305.test.methodInjection.HelloRandom.java

//一个代理接口
public interface HelloRandom {
	
	public RandomT getRandom();
	public abstract RandomT createRandom(); // 这个方法最为重要,是方法注入的关键
	
}

 

com.spring305.test.methodInjection.HelloAbstract.java

public abstract class HelloAbstract implements HelloRandom {

	private RandomT random;
	public void setRandom(RandomT random) {
		this.random = random;
	}

	public abstract RandomT createRandom();

	@Override
	public RandomT getRandom() {
		// TODO Auto-generated method stub
		return this.random;
	}
}

 

src/methodInjection.xml

 <!-- 方法注入-->
     <bean id="myRandom" class="com.spring305.test.methodInjection.RandomT"  scope="prototype" />
     <!--  scope="singleton" -->
     <bean id="helloRandom" class="com.spring305.test.methodInjection.HelloAbstract" >
           <lookup-method name="createRandom" bean="myRandom"/>
           <property name="random">
                   <ref local="myRandom" />    
           </property>
    </bean>

 Test

//@Test
public void testMethodInjection(){
        ApplicationContext context = new ClassPathXmlApplicationContext("methodInjection.xml");
         HelloRandom helloRandom1 = (HelloRandom)context.getBean("helloRandom");
         System.out.println("下面两个实例没有采用方法注入");
         RandomT r1 = helloRandom1.getRandom();
         RandomT r2 = helloRandom1.getRandom();
         System.out.println("Random 的两个实例是否指向同一个引用:" + (r1 == r2));
         r1.printRandom();
         r2.printRandom();
         System.out.println();
         System.out.println("下面两个实例采用方法注入");
         HelloRandom helloRandom = (HelloRandom)context.getBean("helloRandom");
         RandomT r3 = helloRandom.createRandom();
         RandomT r4 = helloRandom.createRandom();
         System.out.println("Random 的两个实例是否指向同一个引用:" + (r3 == r4));
         r3.printRandom();
         r4.printRandom();
}

 

另官方没有给这种Lookup方法注入而是提供了:Arbitrary method replacement方法替换:

com.spring305.test.methodInjection.MyValueCalculator.java

public class MyValueCalculator {

	public String computeValue(String input) {
		return input+"_"+(int)(100*Math.random());
	}

}

 

com.spring305.test.methodInjection.ReplacementComputeValue.java

public class ReplacementComputeValue implements MethodReplacer {

	@Override
	public Object reimplement(Object obj, Method method, Object[] args)
			throws Throwable {
		String input = (String) args[0];
		input += "123";
		
		return input;
	}
}

 xml中再加上:

  <bean id="myValueCalculator" class="com.spring305.test.methodInjection.MyValueCalculator">
	<!-- arbitrary method replacement -->
	<replaced-method name="computeValue" replacer="replacementComputeValue">
		<arg-type>String</arg-type> 
	</replaced-method>
	<!-- <replaced-method name="computeValue" replacer="helloReplacer"/> -->
</bean>
<bean id="replacementComputeValue" class="com.spring305.test.methodInjection.ReplacementComputeValue"/>

 

测试:

@Test
	public void testMethod(){
		 ApplicationContext context = new ClassPathXmlApplicationContext("methodInjection.xml");
		 ReplacementComputeValue reValue = context.getBean("replacementComputeValue",ReplacementComputeValue.class);
		 
		 MyValueCalculator myValueCalculator = context.getBean("myValueCalculator",MyValueCalculator.class);
		 System.out.println(myValueCalculator.computeValue("add"));;
		 
	}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值