首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > 软件架构设计 >

步骤注入

2012-10-09 
方法注入?? 在大部分情况下,IoC容器中的bean都是singleton类型的。如果一个singleton bean要引用另一个sing

方法注入

?? 在大部分情况下,IoC容器中的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实例。

??? 上述问题的一个解决办法就是放弃控制反转。通过实现BeanFactoryAware接口让bean A能够感知bean容器,并且在需要的时候通过使用getBean("B")方式向容器请求一个新的bean B实例。看下面这个例子,其中故意使用了这种方法:

// 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();}

???? 在包含被注入方法的客户类中(此处是CommandManager),此方法的定义必须按照以下形式进行:

<public|protected> [abstract] <return-type> theMethodName(no-arguments);

??? 如果方法是抽象的,动态生成的子类会实现该方法。否则,动态生成的子类会覆盖类里面的具体方法。让我们来看个例子:

<!-- a stateful bean deployed as a prototype (non-singleton) --><bean id="command" scope="prototype">  <!-- inject dependencies here as required --></bean><!-- commandProcessor uses statefulCommandHelper --><bean id="commandManager" bean="command"/></bean>

???? 在上面的例子中,标识为commandManager的bean在需要一个新的coummand bean实例时,会调用createCommand方法。重要的一点是,必须将command部署为原型。当然也可以指定为singleton,如果是这样的话,那么每次将返回相同的command bean实例。

??? Lookup方法注入既可以结合构造器注入,也可以与setter注入相结合。

??? 注意,为了让这个动态子类得以正常工作,需要把CGLIB的jar文件放在classpath里。另外,Spring的容器要子类化的类不能是final的,要覆盖的方法不能是final的。同样的,要测试一个包含抽象方法的类呀稍微有些不同,你需要自己编写它的子类提供抽象方法的实现。最后作为方法注入目标的bean不能是序列化的(serialized)。

?

自定义方法的替代方案

??? 比起Lookup方法注入,还有一种很少用到的方法注入形式,该注入能使用bean的另一个方法实现去替换自定义的方法。

??? 当使用基于XML配置元数据文件时,可以在bean定义中使用replaced-method元素来达到另一个方法来取代已有方法的目的。考虑下面的类,我们将覆盖computeValue方法:

public class MyValueCalculator {  public String computeValue(String input) {    // some real code...  }  // some other methods...}

? ? 实现org.springframework.beans.factory.support.MethodReplacer接口的类提供了新的方法定义。

/** 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定义中指定了将要复写的方法以及执行替换处理的bean定义:

<bean id="myValueCalculator" replacer="replacementComputeValue">    <arg-type>String</arg-type>  </replaced-method></bean><bean id="replacementComputeValue" name="code">java.lang.StringStringStr

???? 参数的个数通常足够用来区别每个可能的选择,这个捷径能减少很多键盘输入的工作,它允许你只输入最短的匹配参数类型的字符串。

热点排行