Spring系列十:Spring FactoryBean

重疊淚痕緘錦字,人生只有情難死。java

概述

工廠bean是用做在IoC容器中建立其餘bean的工廠,但它是特定的Spring的bean。從概念上講,工廠bean很是相似於工廠方法,能夠在bean構造期間由Spring IoC容器標識,而且能夠由容器用來實例化其餘beanspring

使用FactoryBean建立bean

要建立工廠bean,你只須要把建立的bean類實現FactoryBean接口,該類將建立實際所須要的bean。簡單起見,您能夠擴展AbstractFactoryBean類。app

經過擴展AbstractFactoryBean類,工廠Bean能夠簡單地重寫createInstance()方法來建立目標Bean實例。此外,你必須在getObjectType()方法中返回目標bean的類型,spring的自動裝配功能才能正常工做。框架

public class EmployeeFactoryBean extends AbstractFactoryBean<Object> {
    /This method will be called by container to create new instances
    @Override
    protected Object createInstance() throws Exception {
        //code
    }
 
    //This method is required for autowiring to work correctly
    @Override
    public Class<EmployeeDTO> getObjectType() {
        return EmployeeDTO.class;
    }
}
複製代碼

爲何使用工廠bean

工廠bean主要用於實現框架某些特定功能。以下:ide

  1. JNDI查找對象(例如數據源)時,可使用JndiObjectFactoryBean
  2. 使用經典的Spring AOPbean建立代理時,可使用ProxyFactoryBean
  3. IoC容器中建立Hibernate會話工廠時,可使用LocalSessionFactoryBean

在大多數狀況下,你幾乎沒必要編寫任何自定義工廠bean,由於它們框架的特定功能的,而且不能在Spring IoC容器範圍以外使用。測試

FactoryBean 測試

在這個例子中,我正在建立一個工廠bean來實例化不一樣類型的Employee對象,例如他們的manager, director等具備一些預先填充的屬性。ui

EmployeeDTO代碼以下:this

package cn.howtodoinjava.demo.model;
 
public class EmployeeDTO {
 
    private Integer id;
    private String firstName;
    private String lastName;
    private String designation;
 
    //Setters and Getters are hidden behind this comment.
 
    @Override
    public String toString() {
        return "Employee [id=" + id + ", firstName=" + firstName
                + ", lastName=" + lastName + ", type=" + designation + "]";
    }
}
複製代碼

EmployeeFactoryBean類繼承了AbstractFactoryBean類,並實現了兩個方法createInstance()getObjectType()spa

import org.springframework.beans.factory.config.AbstractFactoryBean;
 
import cn.howtodoinjava.demo.model.EmployeeDTO;
 
public class EmployeeFactoryBean extends AbstractFactoryBean<Object> {
    private String designation;
     
    public String getDesignation() {
        return designation;
    }
 
    public void setDesignation(String designation) {
        this.designation = designation;
    }
 
    //This method will be called by container to create new instances
    @Override
    protected Object createInstance() throws Exception {
        EmployeeDTO employee = new EmployeeDTO();
        employee.setId(-1);
        employee.setFirstName("dummy");
        employee.setLastName("dummy");
        //Set designation here
        employee.setDesignation(designation);
        return employee;
    }
 
    //This method is required for autowiring to work correctly
    @Override
    public Class<EmployeeDTO> getObjectType() {
        return EmployeeDTO.class;
    }
}
複製代碼

在配置文件中定義各類Employee類型,以下所示。代理

<bean id="manager" class="cn.howtodoinjava.demo.factory.EmployeeFactoryBean">
    <property name="designation" value="Manager" />
</bean>
 
<bean id="director" class="cn.howtodoinjava.demo.factory.EmployeeFactoryBean">
    <property name="designation" value="Director" />
</bean>

複製代碼

測試工廠bean

public class TestSpringContext {
    @SuppressWarnings("resource")
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
 
        EmployeeDTO manager = (EmployeeDTO) context.getBean("manager");
        System.out.println(manager);
         
        EmployeeDTO director = (EmployeeDTO) context.getBean("director");
        System.out.println(director);
    }
}
複製代碼

輸出:

Employee [id=-1, firstName=dummy, lastName=dummy, type=Manager]
Employee [id=-1, firstName=dummy, lastName=dummy, type=Director]
複製代碼

如你所見,EmployeeFactoryBean使用相同的工廠方法建立了兩個不一樣的員工對象。

獲取FactoryBean實例自己

若是要獲取EmployeeFactoryBean自己的實例,則能夠在bean名稱以前添加

EmployeeFactoryBean factory = (EmployeeFactoryBean) context.getBean("&director");
 
System.out.println(factory.getDesignation());
System.out.println(factory.getObjectType());
System.out.println(factory.getObject());
複製代碼

輸出:

Director
 
class cn.howtodoinjava.demo.model.EmployeeDTO
 
Employee [id=-1, firstName=dummy, lastName=dummy, type=Director]
複製代碼

原文連接:Spring FactoryBean Example

相關文章
相關標籤/搜索