重叠泪痕缄锦字,人生只有情难死。
工厂bean
是用作在IoC
容器中创建其他bean
的工厂,但它是特定的Spring
的bean。从概念上讲,工厂bean
非常类似于工厂方法,可以在bean
构造期间由Spring
IoC
容器标识,并且可以由容器用来实例化其他bean
。
FactoryBean
创建bean
要创建工厂bean
,你只需要把创建的bean
类实现FactoryBean
接口,该类将创建实际所需要的bean
。简单起见,您可以扩展AbstractFactoryBean
类。
通过扩展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
主要用于实现框架某些特定功能。如下:
JNDI
查找对象(例如数据源)时,可以使用JndiObjectFactoryBean
。Spring
AOP
为bean
创建代理时,可以使用ProxyFactoryBean
。IoC
容器中创建Hibernate
会话工厂时,可以使用LocalSessionFactoryBean
。在大多数情况下,你几乎不必编写任何自定义工厂bean
,因为它们框架的特定功能的,并且不能在Spring
IoC
容器范围之外使用。
FactoryBean
测试在这个例子中,我正在创建一个工厂bean
来实例化不同类型的Employee
对象,例如他们的manager
, director
等具有一些预先填充的属性。
EmployeeDTO
代码如下:
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()
。
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]