重叠泪痕缄锦字,人生只有情难死。
概述
工厂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。 - 使用经典的
SpringAOP为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]
🙂🙂🙂关注微信公众号java干货 不定期分享干货资料

