1、lookup-method注入
lookup method注入是spring動態改變bean里方法的實現。方法執行返回的對象,使用spring內原有的這類對象替換,通過改變方法返回值來動態改變方法。內部實現為使用cglib方法,重新生成子類,重寫配置的方法和返回對象,達到動態改變的效果。
實例如下:
package fiona.apple; // no more Spring imports! public abstract class CommandManager { public Object process(Object commandState) { // grab a new instance of the appropriate Command interface Command command = createCommand(); // set the state on the (hopefully brand new) Command instance command.setState(commandState); return command.execute(); } // okay... but where is the implementation of this method? protected abstract Command createCommand(); }
配置:
<bean id="command" class="fiona.apple.AsyncCommand" scope="prototype">
</bean>
<bean id="commandManager" class="fiona.apple.CommandManager"> <lookup-method name="createCommand" bean="command"/> </bean>
注意:由於采用cglib生成之類的方式,所以需要用來動態注入的類,不能是final修飾的;需要動態注入的方法,也不能是final修飾的。
同時,還得注意command的scope的配置,如果scope配置為singleton,則每次調用方法createCommand,返回的對象都是相同的;如果scope配置為prototype,則每次調用,返回都不同。
2、replaced-method注入
replaced method注入是spring動態改變bean里方法的實現。需要改變的方法,使用spring內原有其他類(需要繼承接口org.springframework.beans.factory.support.MethodReplacer)的邏輯,替換這個方法。通過改變方法執行邏輯來動態改變方法。內部實現為使用cglib方法,重新生成子類,重寫配置的方法和返回對象,達到動態改變的效果。
實例如下:
public class MyValueCalculator { public String computeValue(String input) { // some real code... } // some other methods... } /** * meant to be used to override the existing computeValue(String) * implementation in MyValueCalculator */ public class ReplacementComputeValue implements MethodReplacer { public Object reimplement(Object o, Method m, Object[] args) throws Throwable { // get the input value, work with it, and return a computed result String input = (String) args[0]; ... return ...; } }
配置:
<bean id="myValueCalculator" class="x.y.z.MyValueCalculator">
<!-- arbitrary method replacement -->
<replaced-method name="computeValue" replacer="replacementComputeValue">
<arg-type>String</arg-type>
</replaced-method>
</bean>
<bean id="replacementComputeValue" class="a.b.c.ReplacementComputeValue"/>
注意:由於采用cglib生成之類的方式,所以需要用來動態注入的類,不能是final修飾的;需要動態注入的方法,也不能是final修飾的。