Spring5核心原理-FactoryBean详解

教程分享 > Java教程 > Spring (1045) 2024-08-07 11:05:25
FactoryBean 是用作在IoC 容器中创建其他 bean 的工厂bean 。从概念上讲,FactoryBean 与factory method非常相似,但它是 Spring 特定的 bean,可以在 bean 构建过程中被 Spring IoC 容器识别,并且可以被容器用来实例化其他 bean。

使用 FactoryBean 创建 bean

要创建一个工厂 bean,您所要做的就是FactoryBean通过您的创建者 bean 类实现接口,该类将创建实际的其他 bean。或者为了简单起见,您可以扩展AbstractFactoryBean类。
通过扩展AbstractFactoryBean类,您的工厂 bean 可以简单地覆盖createInstance()创建目标 bean 实例的方法。此外,您必须在getObjectType()方法中返回目标 bean 的类型才能使自动装配功能正常工作。
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;
    }
}

为什么要使用FactoryBean?

FactoryBean主要用于实现框架设施。这里有些例子:
  1. 从 JNDI 中查找对象(例如数据源)时,可以使用JndiObjectFactoryBean.
  2. 当使用经典 Spring AOP 为 bean 创建代理时,您可以使用ProxyFactoryBean.
  3. 在 IoC 容器中创建 Hibernate 会话工厂时,可以使用LocalSessionFactoryBean.
在大多数情况下,您很少需要编写任何自定义工厂 bean,因为它们是特定于框架的,并且不能在 Spring IoC 容器的范围之外使用。
 

FactoryBean 演示

在这个例子中,我正在创建一个FactoryBean 来实例化不同类型的Employee对象,例如它们的manager、director等,并带有一些预填充的属性。
我们的EmployeeDTO班级是这样的。
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 com.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="com.howtodoinjava.demo.factory.EmployeeFactoryBean">
	<property name="designation" value="Manager" />
</bean>

<bean id="director"  class="com.howtodoinjava.demo.factory.EmployeeFactoryBean">
	<property name="designation" value="Director" />
</bean>
要测试上述FactoryBean,请使用以下代码:
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 name 之前添加一个“&”
EmployeeFactoryBean factory = (EmployeeFactoryBean) context.getBean("&director");
 
System.out.println(factory.getDesignation());
System.out.println(factory.getObjectType());
System.out.println(factory.getObject());
 

输出:
Director
 
class com.leftso.demo.model.EmployeeDTO
 
Employee [id=-1, firstName=dummy, lastName=dummy, type=Director]


 
https://www.leftso.com/article/1001.html

相关文章
FactoryBean 是用作在IoC 容器中创建其他 bean 的工厂bean 。从概念上讲,FactoryBean 与factory method非常相似,但它是 Spring 特定的 be...
Spring框架Spring IoC容器的核心原理,前三篇已经从历史的角度和大家一起探讨了为什么会有Spring,Spring的两个核心概念:IoC和AOP的雏形,Spring的历史变迁和如今的...
了解将资源或文件(例如文本文件、XML 文件、属性文件或图像文件)加载到 Spring 应用程序上下文中的不同方法。Spring ResourceLoader为我们通过资源路径getResour...
Spring boot 入门之CORS 跨域配置详解,spring 跨域配置详解。
前言    本教程主要讲解spring boot如何整合 spring data elasticsearch 实现elasticsearch检索引擎的整合使用
Spring AOP 实现原理基础讲解
在 Spring 框架中,如果您想通过调用静态工厂方法来创建 bean ,其目的是将对象创建过程封装在static方法中,那么您可以使用factory-method属性。静态工厂方法示例如果你想...
在 Spring 框架中,我们可以在 6 个内置的spring bean 作用域内创建 bean ,您也可以定义自定义 bean 作用域。在这六个作用域中,只有在您使用 Web 感知的Appli...
引言    通过之前spring boot mybatis 整合的讲解: spring boot mybaties整合  (spring boot mybaties 整合 基于Java注解方式写...
在 Spring 框架中,按类型自动装配 bean 允许自动装配属性 -如果容器中只有一个属性类型的 bean。如果有多个,则会抛出一个致命异常,这表明您可能不会byType对该 bean 使用...
在 Spring 框架中,通过构造函数自动装配 bean类似于byType,但适用于构造函数参数。在启用自动装配的 bean 中,它查找构造函数参数的类类型,然后按类型对所有构造函数参数执行自动...
了解Spring bean 生命周期。我们将了解 bean生命周期阶段、初始化和销毁​​回调方法。我们将学习使用 XML 配置以及 Java 注释配置来自定义 bean 生命周期事件。1. 什么...
spring boot 入门之spring session实现restful apis。通过spring boot或者spring mvc整合spring session的方式来实现sessio...
在 Spring 框架中,在配置文件中声明 bean 依赖项是一个很好的做法,因此 Spring 容器能够自动装配协作 bean 之间的关系。这意味着可以通过检查BeanFactory的内容让 ...
spring boot 入门之整合spring session实现session共享。一直以来Java编程中web项目中的session共享问题都是一个很难解决的问题。接下来将讲解通过sprin...