Spring3之 bean Method injection

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.csdn.net/zml2004/archive/2006/04/15/664309.aspx例子

Lookup Method Injection 

 

 

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

 
     
     
     
           
           
                       
           
    

 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中再加上:

  
	
	
		String 
	
	

 

测试:

@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"));;
		 
	}

 

 

你可能感兴趣的:(spring)