spring中BeanFactory和FactoryBean的區別


共同點:

         都是接口

區別:

      BeanFactory 以Factory結尾,表示它是一個工廠類,用於管理Bean的一個工廠

             在Spring中,所有的Bean都是由BeanFactory(也就是IOC容器)來進行管理的。

     對FactoryBean而言,這個Bean不是簡單的Bean,而是一個能生產或者修飾對象生成的工廠Bean,

             它的實現與設計模式中的工廠模式和修飾器模式類似。

 

1、 BeanFactory

     BeanFactory定義了IOC容器的最基本形式,並提供了IOC容器應遵守的的最基本的接口,也就是Spring IOC所遵守的最底層和最基本的編程規范

     它的職責包括:實例化、定位、配置應用程序中的對象及建立這些對象間的依賴。

    在Spring代碼中,BeanFactory只是個接口,並不是IOC容器的具體實現,

          但是Spring容器給出了很多種實現,如 DefaultListableBeanFactory、XmlBeanFactory、ApplicationContext等,都是附加了某種功能的實現。

 

package org.springframework.beans.factory;

import org.springframework.beans.BeansException;
import org.springframework.core.ResolvableType;

public interface BeanFactory {
    String FACTORY_BEAN_PREFIX = "&";

    Object getBean(String var1) throws BeansException;

    <T> T getBean(String var1, Class<T> var2) throws BeansException;

    <T> T getBean(Class<T> var1) throws BeansException;

    Object getBean(String var1, Object... var2) throws BeansException;

    <T> T getBean(Class<T> var1, Object... var2) throws BeansException;

    boolean containsBean(String var1);

    boolean isSingleton(String var1) throws NoSuchBeanDefinitionException;

    boolean isPrototype(String var1) throws NoSuchBeanDefinitionException;

    boolean isTypeMatch(String var1, ResolvableType var2) throws NoSuchBeanDefinitionException;

    boolean isTypeMatch(String var1, Class<?> var2) throws NoSuchBeanDefinitionException;

    Class<?> getType(String var1) throws NoSuchBeanDefinitionException;

    String[] getAliases(String var1);
}
View Code

 

 

2、FactoryBean
      一般情況下,Spring通過反射機制利用<bean>的class屬性指定實現類實例化Bean,在某些情況下,實例化Bean過程比較復雜,

如果按照傳統的方式,則需要在<bean>中提供大量的配置信息。配置方式的靈活性是受限的,這時采用編碼的方式可能會得到一個簡單的方案。

Spring為此提供了一個org.springframework.bean.factory.FactoryBean的工廠類接口,用戶可以通過實現該接口定制實例化Bean的邏輯
      FactoryBean接口對於Spring框架來說占用重要的地位,Spring自身就提供了70多個FactoryBean的實現。

它們隱藏了實例化一些復雜Bean的細節,給上層應用帶來了便利。從Spring3.0開始,FactoryBean開始支持泛型,即接口聲明改為FactoryBean<T>的形式

 

package org.springframework.beans.factory;

public interface FactoryBean<T> {
    T getObject() throws Exception;

    Class<?> getObjectType();

    boolean isSingleton();
}
View Code

在該接口中還定義了以下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>元素標簽。

 

    package  com.baobaotao.factorybean;  
    public   class  Car  {  
        private   int maxSpeed ;  
        private  String brand ;  
        private   double price ;  
        public   int  getMaxSpeed ()   {  
            return   this . maxSpeed ;  
        }  
        public   void  setMaxSpeed ( int  maxSpeed )   {  
            this . maxSpeed  = maxSpeed;  
        }  
        public  String getBrand ()   {  
            return   this . brand ;  
        }  
        public   void  setBrand ( String brand )   {  
            this . brand  = brand;  
        }  
        public   double  getPrice ()   {  
            return   this . price ;  
        }  
        public   void  setPrice ( double  price )   {  
            this . price  = price;  
       }  
}   

     如果用FactoryBean的方式實現就靈活點,下例通過逗號分割符的方式一次性的為Car的所有屬性指定配置值: 

package  com.baobaotao.factorybean;  
import  org.springframework.beans.factory.FactoryBean;  
public   class  CarFactoryBean  implements  FactoryBean<Car>  {  
    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<Car> getObjectType ()   {  
        return  Car. class ;  
    }  
    public   boolean  isSingleton ()   {  
        return   false ;  
    }  
    public  String getCarInfo ()   {  
        return   this . carInfo ;  
    }  
  
    // 接受逗號分割符設置屬性信息  
    public   void  setCarInfo ( String carInfo )   {  
        this . carInfo  = carInfo;  
    }  
}   

 有了這個CarFactoryBean后,就可以在配置文件中使用下面這種自定義的配置方式配置CarBean了:

<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 Others:

   3.1 Spring中共有兩種bean,一種為普通bean,另一種則為工廠bean。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM