Spring中的BeanFatory和FactoryBean

BeanFactory

  表示它是一個工廠類(接口), 它負責生產和管理bean的一個工廠。,在 Spring 中,BeanFactory是 IoC 容器的核心接口。它的職責包括:實例化、定位、配置應用程序中的對象及創建這些對象間的依賴。BeanFactory只是個接口,並非IOC容器的具體實現,可是Spring容器給出了不少種實現,如 DefaultListableBeanFactory、XmlBeanFactory、ApplicationContext等。BeanFactory 提供的高級配置機制,使得管理任何性質的對象成爲可能。ApplicationContext 是 BeanFactory 的擴展,功能獲得了進一步加強,好比更易與 Spring AOP 集成、消息資源處理(國際化處理)、事件傳遞及各類不一樣應用層的 context 實現(如針對 web 應用的WebApplicationContext)。web

  用的比較多的BeanFactory 的子類是ClassPathXmlApplicationContext,這是 ApplicationContext接口的一個子類,ClassPathXmlApplicationContext 從 xml 的配置文件中獲取 bean 而且管理他們spring

  BeanFactory和ApplicationContext就是spring框架的兩個IOC容器,如今通常使用ApplicationnContext,其不但包含了BeanFactory的做用,同時還進行更多的擴展。  設計模式

  BeanFacotry是spring中比較原始的Factory。如XMLBeanFactory就是一種典型的BeanFactory。原始的BeanFactory沒法支持spring的許多插件,如AOP功能、Web應用等。ApplicationContext接口,它由BeanFactory接口派生而來,ApplicationContext包含BeanFactory的全部功能,一般建議比BeanFactory優先。ApplicationContext以一種更向面向框架的方式工做以及對上下文進行分層和實現繼承。框架

 

 

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>的形式ide

  Spring 中爲咱們提供了兩種類型的 bean,一種就是普通的 bean,咱們經過 getBean(id) 方法得到是該 bean 的實際類型,另外還有一種 bean 是 FactoryBean,也就是工廠 bean,咱們經過 getBean(id)得到是該工廠所產生的 Bean 的實例,而不是該 FactoryBean 的實例。this

  FactoryBean 是一個 Bean,實現了 FactoryBean 接口的類有能力改變 bean,FactoryBean 但願你實現了它以後返回一些內容,Spring 會按照這些內容去註冊 bean。不一樣於普通Bean的是:它是實現了FactoryBean<T>接口的Bean,根據該Bean的ID從BeanFactory中獲取的其實是FactoryBean的getObject()返回的對象,而不是FactoryBean自己,若是要獲取FactoryBean對象,請在id前面加一個&符號來獲取。編碼

 

區別

  BeanFactory是個Factory,也就是IOC容器或對象工廠,FactoryBean是個Bean。在Spring中,全部的Bean都是由BeanFactory(也就是IOC容器)來進行管理的。但對FactoryBean而言,這個Bean不是簡單的Bean,而是一個能生產或者修飾對象生成的工廠Bean,它的實現與設計模式中的工廠模式和修飾器模式相似 spa

 

FactoryBean接口,提供以下方法:插件

public interface FactoryBean<T> {

    T getObject() throws Exception;

    Class<?> getObjectType();

    boolean isSingleton();
}
  一般狀況下,bean 無須本身實現工廠模式,Spring 容器擔任工廠 角色;但少數狀況下,容器中的 bean 自己就是工廠,做用是產生其餘 bean 實例。由工廠 bean 產生的其餘 bean 實例,再也不由 Spring 容器產生,所以與普通 bean 的配置不一樣,再也不須要提供 class 元素。

示例:
public class StudentFactoryBean implements FactoryBean<Student> {
    private String name;
    private int age;

    @Override  //注意getObject()返回的是由FactoryBean建立的bean實例  
    public Student getObject() throws Exception {
        return new Student(name, age);
    }

    @Override
    public Class<?> getObjectType() {  //注意:getObjectType()返回的類型纔是FactoryBean建立的真正的bean類型,類型並非StudentFactoryBean return Student.class;
    }

    /**
     * 工廠所管理的對象是否爲單例的
     * 即若是該方法返回true,那麼經過getObject()方法返回的對象都是同一個對象
     */
    @Override
    public boolean isSingleton() {
        return true;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

  xml配置:設計

<bean id="studentFactoryBean" class="spring.StudentFactoryBean">
    <property name="name" value="Tom"/>
    <property name="age" value="28"/>
</bean>

  使用:

public static void main(String[] args) throws Exception {
    BeanFactory bf = new ClassPathXmlApplicationContext("student.xml");
    Student studentBean = (Student) bf.getBean("studentFactoryBean");

    studentBean.print();
}
相關文章
相關標籤/搜索