BeanFactory与FactoryBean

  • BeanFactory
    表示它是一个工厂类(接口), 它负责生产和管理bean的一个工厂。在Spring中,BeanFactory是IOC容 器的核心接口,它的职责包括:实例化、定位、配置应用程序中的对象及建立这些对象间的依赖
    BeanFactory只是个接口,并不是IOC容器的具体实现,但是Spring容器给出了多种实现,如 DefaultListableBeanFactory、XmlBeanFactory、ApplicationContext等,XmlBeanFactory就是常用的一个,该实现将以XML方式描述组成应用的对象及对象间的依赖关系。XmlBeanFactory类将持有此XML配置元数据,并用它来构建一个完全可配置的系统或应用。
package org.springframework.beans.factory;  
import org.springframework.beans.BeansException;  

public interface BeanFactory {  
 
    String FACTORY_BEAN_PREFIX = "&";  //FactoryBean解引用符,getBean时加上获取FactoryBean实例
   
    Object getBean(String name) throws BeansException;  //根据名称获取Bean
  
     T getBean(String name, Class requiredType) throws BeansException;  
  
     T getBean(Class requiredType) throws BeansException;  
   
    Object getBean(String name, Object... args) throws BeansException;  
   
    boolean containsBean(String name);  //容器是否包含该名称的Bean
   
    boolean isSingleton(String name) throws NoSuchBeanDefinitionException;  //是否为单例
   
    boolean isPrototype(String name) throws NoSuchBeanDefinitionException;  //是否为多例
    
    boolean isTypeMatch(String name, Class targetType) throws NoSuchBeanDefinitionException; //查询指定了名字的Bean的Class类型是否是特定的Class类型。这个Class类型可以由用户来指定。
   
    Class getType(String name) throws NoSuchBeanDefinitionException;  //查询指定名字的Bean的  Class类型
    
    String[] getAliases(String name);  //获取别名, 这些别名都是用户在BeanDefinition中定义的。

}
  • FactoryBean
    一般情况下,Spring通过反射机制利用的class属性指定实现类实例化Bean,在某些情况下,实例化Bean过程比较复杂,如果按照传统的方式,则需要在中提供大量的配置信息。配置方式的灵活性是受限的,这时采用编码的方式可能会得到一个简单的方案。
    Spring为此提供了一个org.springframework.bean.factory.FactoryBean的工厂类接口,用户可以通过实现该接口定制实例化Bean的逻辑。 FactoryBean接口对于Spring框架来说占用重要的地位,Spring自身就提供了70多个FactoryBean的实现。它们隐藏了实例化一些复杂Bean的细节,
    给上层应用带来了便利。从Spring3.0开始,FactoryBean开始支持泛型,即接口声明改为FactoryBean的形式。
package org.springframework.beans.factory;  

public interface FactoryBean {  
   
    T getObject() throws Exception;  //返回实例化Bean对象
   
    Class getObjectType();  //返回实例化Bean的类型
  
    boolean isSingleton();  //Bean是否为单例, 为true,则该实例会放到Spring容器中单实例缓存池中。

}
  • FactoryBean 使用举例
    定义一个Car实体,包含最大速度、品牌、价格等属性,如果使用传统方式配置下面Car的时,Car的每个属性分别对应一个元素标签。
public   class  Car  {    
       private   int maxSpeed ;    
       private  String brand ;    
       private   double price ;    
      //get/set方法  
}

​ 可以通过FactoryBean以分隔符的形式一次性指定所有属性值

public   class  CarFactoryBean  implements  FactoryBean  {    
    
    private  String carInfo ;    
    
    public  Car getObject ()   throws  Exception  {    
        Car car =  new  Car () ;    
        String []  infos =  carInfo .split ( "," ) ;    
        car.setBrand ( infos [ 0 ]) ;    
        car.setMaxSpeed ( Integer. valueOf ( infos [ 1 ])) ;    
        car.setPrice ( Double. valueOf ( infos [ 2 ])) ;    
        return  car;    
    }    
  
    public  Class getObjectType ()   {    
        return  Car.class ;    
    }    
   
    public   boolean  isSingleton ()   {    
        return   false ;    
    }    
   
    public  String getCarInfo ()   {    
        return   this.carInfo ;    
    }    
    
    // 接受逗号分割符设置属性信息    
    public   void  setCarInfo ( String carInfo )   {    
        this.carInfocarInfo  = carInfo;    
    }    
}  

​ XML配置

     

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

  • BeanFactory和FactoryBean的区别
    BeanFactory和FactoryBean其实没有什么比较的,只是两者的名称特别接近,BeanFactory是提供了IOC容器最基本的形式,给具体的IOC容器的实现提供了规范。FactoryBean可以 说为IOC容器中Bean的实现提供了更加灵活的方式,FactoryBean在IOC容器的基础上给Bean的实现加上了一个简单工厂模式和装饰模式,我们可以在getObject()方法中灵活配置。其实在Spring源码中有很多FactoryBean的实现类,要想深入准确的理解FactoryBean,只有去读读Spring源码了。

参考链接

  1. [FactoryBean的使用]
  2. [Spring IoC容器的设计——BeanFactory应用场景]

你可能感兴趣的:(BeanFactory与FactoryBean)