前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Spring系列十:Spring FactoryBean

Spring系列十:Spring FactoryBean

作者头像
java干货
发布2021-02-19 10:38:11
4290
发布2021-02-19 10:38:11
举报
文章被收录于专栏:java干货

重叠泪痕缄锦字,人生只有情难死。

概述

工厂bean是用作在IoC容器中创建其他bean的工厂,但它是特定的Spring的bean。从概念上讲,工厂bean非常类似于工厂方法,可以在bean构造期间由Spring IoC容器标识,并且可以由容器用来实例化其他bean

使用FactoryBean创建bean

要创建工厂bean,你只需要把创建的bean类实现FactoryBean接口,该类将创建实际所需要的bean。简单起见,您可以扩展AbstractFactoryBean类。

通过扩展AbstractFactoryBean类,工厂Bean可以简单地重写createInstance()方法来创建目标Bean实例。此外,你必须在getObjectType()方法中返回目标bean的类型,spring的自动装配功能才能正常工作。

代码语言:javascript
复制
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主要用于实现框架某些特定功能。如下:

  1. JNDI查找对象(例如数据源)时,可以使用JndiObjectFactoryBean
  2. 使用经典的Spring AOPbean创建代理时,可以使用ProxyFactoryBean
  3. IoC容器中创建Hibernate会话工厂时,可以使用LocalSessionFactoryBean

在大多数情况下,你几乎不必编写任何自定义工厂bean,因为它们框架的特定功能的,并且不能在Spring IoC容器范围之外使用。

FactoryBean 测试

在这个例子中,我正在创建一个工厂bean来实例化不同类型的Employee对象,例如他们的manager, director等具有一些预先填充的属性。

EmployeeDTO代码如下:

代码语言:javascript
复制
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()

代码语言:javascript
复制
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类型,如下所示。

代码语言:javascript
复制
<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

代码语言:javascript
复制
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);
    }
}

输出:

代码语言:javascript
复制
Employee [id=-1, firstName=dummy, lastName=dummy, type=Manager]
Employee [id=-1, firstName=dummy, lastName=dummy, type=Director]

如你所见,EmployeeFactoryBean使用相同的工厂方法创建了两个不同的员工对象。

获取FactoryBean实例本身

如果要获取EmployeeFactoryBean本身的实例,则可以在bean名称之前添加

代码语言:javascript
复制
EmployeeFactoryBean factory = (EmployeeFactoryBean) context.getBean("&director");
 
System.out.println(factory.getDesignation());
System.out.println(factory.getObjectType());
System.out.println(factory.getObject());

输出:

代码语言:javascript
复制
Director
 
class cn.howtodoinjava.demo.model.EmployeeDTO
 
Employee [id=-1, firstName=dummy, lastName=dummy, type=Director]
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019/10/22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 概述
    • 使用FactoryBean创建bean
      • 为什么使用工厂bean
        • FactoryBean 测试
          • 获取FactoryBean实例本身
          相关产品与服务
          容器服务
          腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档