BeanFactory和FactoryBean

Original: http://chenzehe.iteye.com/blog/1481476

1、 BeanFactory

    BeanFactory defines the  most basic form of the IOC  container, and provides the  most basic interface that the IOC  container should comply with, that is  , the lowest level and the most basic programming specification that Spring IOC complies with. In   Spring  code,  BeanFactory  is just an interface, not  a specific implementation of the  IOC container, but the Spring  container provides many implementations, such as  DefaultListableBeanFactory  ,  XmlBeanFactory  , ApplicationContext  , etc., all of which are implementations with additional functions.


Java code   Favorite code
  1. package org.springframework.beans.factory;  
  2. import org.springframework.beans.BeansException;  
  3. public interface BeanFactory {  
  4.     String FACTORY_BEAN_PREFIX = "&";  
  5.     Object getBean(String name) throws BeansException;  
  6.     <T> T getBean(String name, Class<T> requiredType) throws BeansException;  
  7.     <T> T getBean(Class<T> requiredType) throws BeansException;  
  8.     Object getBean(String name, Object... args) throws BeansException;  
  9.     boolean containsBean(String name);  
  10.     boolean isSingleton(String name) throws NoSuchBeanDefinitionException;  
  11.     boolean isPrototype(String name) throws NoSuchBeanDefinitionException;  
  12.     boolean isTypeMatch(String name, Class<?> targetType) throws NoSuchBeanDefinitionException;  
  13.     Class<?> getType(String name) throws NoSuchBeanDefinitionException;  
  14.     String[] getAliases(String name);  
  15. }   
 

 

2、 FactoryBean

    In general, Spring uses  the  class attribute of < bean> to  specify the implementation class to instantiate  beans  through the reflection mechanism   . In some cases, the process of instantiating  beans  is complicated. If the traditional method is used, it is necessary   to provide a large number of configuration information. The flexibility of the configuration method is limited, and a simple solution may be obtained by using the encoding method. Spring  provides a factory class interface of org.springframework.bean.factory.FactoryBean for this purpose, and users can customize  the logic of  instantiating  beans by implementing this interface.

FactoryBean接口对于 Spring 框架来说占用重要的地位, Spring 自身就提供了 70 多个 FactoryBean 的实现。它们隐藏了实例化一些复杂 Bean 的细节,给上层应用带来了便利。从 Spring 3.0 开始, FactoryBean 开始支持泛型,即接口声明改为 FactoryBean<T> 的形式:


Java代码   Favorite code
  1. package org.springframework.beans.factory;  
  2. public interface FactoryBean<T> {  
  3.     T getObject() throws Exception;  
  4.     Class<?> getObjectType();  
  5.     boolean isSingleton();  
  6. }   
 

在该接口中还定义了以下3 个方法:

T getObject():返回由 FactoryBean 创建的 Bean 实例,如果 isSingleton() 返回 true ,则该实例会放到Spring 容器中单实例缓存池中;

boolean isSingleton():返回由 FactoryBean 创建的 Bean 实例的作用域是 singleton 还是 prototype ;

Class<T> getObjectType():返回 FactoryBean 创建的 Bean 类型。

当配置文件中<bean> 的 class 属性配置的实现类是 FactoryBean 时,通过 getBean() 方法返回的不是FactoryBean 本身,而是 FactoryBean#getObject() 方法所返回的对象,相当于 FactoryBean#getObject() 代理了getBean() 方法。

例:如果使用传统方式配置下面Car 的 <bean> 时, Car 的每个属性分别对应一个 <property> 元素标签。


Java代码   Favorite code
  1. package  com.baobaotao.factorybean;  
  2.     public   class  Car  {  
  3.         private   int maxSpeed ;  
  4.         private  String brand ;  
  5.         private   double price ;  
  6.         public   int  getMaxSpeed ()   {  
  7.             return   this . maxSpeed ;  
  8.         }  
  9.         public   void  setMaxSpeed ( int  maxSpeed )   {  
  10.             this . maxSpeed  = maxSpeed;  
  11.         }  
  12.         public  String getBrand ()   {  
  13.             return   this . brand ;  
  14.         }  
  15.         public   void  setBrand ( String brand )   {  
  16.             this . brand  = brand;  
  17.         }  
  18.         public   double  getPrice ()   {  
  19.             return   this . price ;  
  20.         }  
  21.         public   void  setPrice ( double  price )   {  
  22.             this . price  = price;  
  23.        }  
  24. }   
 

如果用FactoryBean 的方式实现就灵活点,下例通过逗号分割符的方式一次性的为 Car 的所有属性指定配置值:


Java代码   Favorite code
  1. package  com.baobaotao.factorybean;  
  2. import  org.springframework.beans.factory.FactoryBean;  
  3. public   class  CarFactoryBean  implements  FactoryBean<Car>  {  
  4.     private  String carInfo ;  
  5.     public  Car getObject ()   throws  Exception  {  
  6.         Car car =  new  Car () ;  
  7.         String []  infos =  carInfo .split ( "," ) ;  
  8.         car.setBrand ( infos [ 0 ]) ;  
  9.         car.setMaxSpeed ( Integer. valueOf ( infos [ 1 ])) ;  
  10.         car.setPrice ( Double. valueOf ( infos [ 2 ])) ;  
  11.         return  car;  
  12.     }  
  13.     public  Class<Car> getObjectType ()   {  
  14.         return  Car. class ;  
  15.     }  
  16.     public   boolean  isSingleton ()   {  
  17.         return   false ;  
  18.     }  
  19.     public  String getCarInfo ()   {  
  20.         return   this . carInfo ;  
  21.     }  
  22.   
  23.     // 接受逗号分割符设置属性信息  
  24.     public   void  setCarInfo ( String carInfo )   {  
  25.         this . carInfo  = carInfo;  
  26.     }  
  27. }   
 

有了这个CarFactoryBean 后,就可以在配置文件中使用下面这种自定义的配置方式配置 Car Bean 了:

<bean id="car" class="com.baobaotao.factorybean.CarFactoryBean" 

    P:carInfo="法拉利 ,400,2000000"/>

当调用getBean("car") 时, Spring 通过反射机制发现 CarFactoryBean 实现了 FactoryBean 的接口,这时Spring 容器就调用接口方法 CarFactoryBean#getObject() 方法返回。如果希望获取 CarFactoryBean 的实例,则需要在使用 getBean(beanName) 方法时在 beanName 前显示的加上 "&" 前缀:如 getBean("&car");

 

3、 区别

    BeanFactory is a  Factory  , that is,  IOC  container or object factory,  FactoryBean  is a  Bean  . In  Spring  , all  beans  are managed by the  BeanFactory (  that is, the  IOC  container  )  . But for  FactoryBean  , this  bean  is not a simple  bean , but a factory bean that  can produce or modify objects  .  Its implementation is similar to the factory pattern and decorator pattern in the design pattern.

 



Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325992534&siteId=291194637