去掉对Spring BeanFacotry的getBean步骤的依赖

去掉对Spring BeanFacotry的getBean方法的依赖
  在使用Spring时,有时会碰到这种情况:
 
引用
需要在一个类中使用一个非Singlton类型的Bean,比如每次方法调用都需要new一个新的Bean。但是,由于Spring的依赖注入是在Bean初始化完成之后进行的,而且只进行一次,因此就无法在每次方法调用时注入新的Bean。

  那么如何解决这个问题呢,一般的做法可能是实现Spring的ApplicationContextAware接口,然后在没个方法中显示地调用ApplicationContext的getBean方法,当然这个Bean在Spring的配置文件中是配置成非Singlton的。如下面代码所示:
public class ClazzA implements ApplicationContextAware{
   private ApplicationContext applicationContext;

   void setApplicationContext(ApplicationContext applicationContext){
       this.applicationContext = applicationContext;
   }

   public void methodA(){
      Object bean = this.applicationContext.getBean("...");
      ...
   }

   public void methodB(){
      Object bean = this.applicationContext.getBean("...");
      ...
   }

   ...
}

  上面的代码可以解决我们之前说的问题,但是,这样做就形成了对Spring框架代码的依赖,降低了应用程序代码的可以执行和可重用性。
  不过不用担心,Spring已经为我们考虑到了这一点,并且提供了几种更好的解决方案。下面讲一下其中的两种。这两种方法Spring都是通过使用CGLIB自动生成字节码来完成的。
  解决方案一:Lookup Method。
  仍然以上面的ClazzA为例。这种方法需要将ClazzA定义为抽象类,并在该类中定义一个抽象的createBean方法。修改后的代码如下:
public abstract class ClazzA{
   public void methodA(){
      ClazzB bean = this.applicationContext.getBean("...");
      ...
   }

   public void methodB(){
      ClazzB bean = this.applicationContext.getBean("...");
      ...
   }

   public abstract ClazzB createBean();
   ...
}

然后在Spring的配置文件中做如下定义:
<bean id="clazzB" class="edu.sjtu.spring.ClazzB" scope="prototype">
  <!-- inject dependencies here as required -->
</bean>

<!-- commandProcessor uses statefulCommandHelper -->
<bean id="clazzA" class="edu.sjtu.spring.ClazzA">
  <lookup-method name="createBean" bean="command"/>
</bean>

这样定义之后,Spring就会使用CGLIB自动生成一个实现了createBean方法的ClazzA的一个实现类,并让createBean返回ClazzB。
上面所说的那个createBean方法必须符合下面的方法签名:
<public|protected> [abstract] <return-type> theMethodName(no-arguments);


详细信息可以参见Spring文档的3.4节。
  解决方案二:使用ServiceLocatorFactoryBean。
  这种方案交第一种方案更加灵活一点,但是付出的代价是要单独定一个工厂接口。这种方法在Spring的ServiceLocatorFactoryBean类的API文档中有详细介绍,这里就不再累述了。