天天看点

Spring内核研究-通过工厂注入

    Spring专门设计了对工厂模式支持,你可以使用静态工厂方法来创建一个Bean,也可以使用实例工厂的方法来创建Bean。下面分别介绍这2种方法。

静态工厂注入

    定义一个Bean使用自己类上的静态工厂方法来创建自己。 我们继续使用上一篇文章《Spring内核研究-Lookup方法注入》的例子来说明如何使用静态工厂创建Bean。 context.xml     factory-menthod定义了userDao Bean使用UserDao类的getInstance方法来创建自己的实例。userManager仍然通过lookup方法获得userDao。Lookup方法并不关心一个Bean的实例时怎样创建的,所以可以混合使用lookup方法和factory-menthod方法。

xml version="1.0" encoding="UTF-8"?>

DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
    "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
    <bean name="userManager"
       class="research.spring.beanfactory.ch2.UserManager">
       <lookup-method name="getUserDao" bean="userDao" />
    bean>
 <bean name="userDao" class="research.spring.beanfactory.ch2.UserDao"
 factory-method="getInstance" / >
beans>
        

UserDao.java     增加一个getInstance方法来创建自己的实例。

package research.spring.beanfactory.ch2;


  public
   
  class
   UserDao {
       
  public
   
  static
   UserDao getInstance() {

              
  return
   
  new
   UserDao(
  "
  static factory method
  "
  );
       }
 
       
  private
   String name 
  =
   
  ""
  ;
 
       
  public
   UserDao(String name) {
              
  this
  .name 
  =
   name;
       }
 
       
  public
   
  void
   create() {

              System.
  out
  .println(
  "
  create user from - 
  "
   
  +
   name);
       }
}
       

Test.java

package research.spring.beanfactory.ch2;

import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
 

  public
   
  class
   Test {
 
       
  public
   
  static
   
  void
   main(String[] args) {

              XmlBeanFactory factory
  =
  new
   XmlBeanFactory(
  new
   ClassPathResource(

  "
  research/spring/beanfactory/ch2/context.xml
  "
  ));

              UserManager manager
  =
  (UserManager) factory.getBean(
  "
  userManager
  "
  );
              manager.createUser();
       }
 
}
       

运行Test.java,你会看到:

create user from - static factory method

这说明userDao使用它自己得静态工厂创建得。   静态工厂方法存在一些限制:

  1. 静态工厂方法上不能有参数,也不能在Spring种定义静态工厂方法的参数。
  2. 静态工厂方法只能是public的,不能是private或protected的。
  3. 静态工厂方法不能和构造函数注入一起使用。下面的定义时不能正常工作的:
package research.spring.beanfactory.ch2;
 
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
 
public class Test {
 
       public static void main(String[] args) {

              XmlBeanFactory factory=new XmlBeanFactory(new ClassPathResource(
"research/spring/beanfactory/ch2/context.xml"));

              UserManager manager=(UserManager) factory.getBean("userManager");
              manager.createUser();
       }
 
}
       
实例工厂注入

    定义一个Bean使用这个Bean的工厂对象上的工厂方法来创建自己。 我们定义一个UserDao的Factory来创建UserDao。 UserDaoFactory.java

package research.spring.beanfactory.ch2;
 
  public
   
  class
   UserDaoFactory{
   
  public
   UserDao getUserDao(){

          
  return
   
  new
   UserDao(
  "
  UserDaoFactory
  "
  );
   }
}
       

修改context.xml:

xml version="1.0" encoding="UTF-8"?>

DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
    "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
    <bean name="userManager"
       class="research.spring.beanfactory.ch2.UserManager">
       <lookup-method name="getUserDao" bean="userDao" />
    bean>
 <bean name="userDao" class="research.spring.beanfactory.ch2.UserDao"
 factory-bean="userDaoFactory" factory-method="getUserDao" >
 bean>  <bean name="userDaoFactory" class="research.spring.beanfactory.ch2.UserDaoFactory">  bean> beans>
       

再次运行Test.java你会看到: create user from – UserDaoFactory       通过上面的配置Spring已经使用userDaoFactory实例的工厂方法来创建userDao了。

  • factory-bean定义了工厂Bean
  • factory-method定义了工厂方法

    实例工厂和静态工厂一样都存在相同的限制:

  1. 静态工厂方法上不能有参数,也不能在Spring种定义静态工厂方法的参数。
  2. 静态工厂方法只能是public的,不能是private或protected的。
  3. 静态工厂方法不能和构造函数注入一起使用。

        和静态工厂不同的是:

  •  实例工厂方法不能是静态的,而静态工厂方法必须是静态的。

    通过上面的例子我们看到Spring对工厂模式对了完整的支持。但是这里还是需要说明,如果使用IoC模式设计的系统一般情况下不需要为任何Bean做工厂类。在我的观点里,工厂模式仅仅是遗留系统,使用依赖注入模式可以取代工厂模式。Spring对工厂的支持仅仅是为了可以很好的集成遗留系统 .