一文搞懂BeanFactory和FactoryBean区别

本文详细介绍了Spring中的BeanFactory接口及其主要实现类,以及FactoryBean接口的作用和使用方法。BeanFactory作为Spring Bean容器的根接口,提供了获取Bean对象的规范。而FactoryBean则用于创建复杂Bean对象,它允许用户自定义Bean的实例化过程。通过示例代码展示了如何在XML配置中使用FactoryBean创建Bean。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

BeanFactory

这个其实是所有Spring Bean的容器根接口,给Spring 的容器定义一套规范,给IOC容器提供了一套完整的规范,比如我们常用到的getBean方法等

The root interface for accessing a Spring bean container. This is the basic client view of a bean container;

定义方法:

  • getBean(String name): Spring容器中获取对应Bean对象的方法,如存在,则返回该对象
  • containsBean(String name):Spring容器中是否存在该对象
  • isSingleton(String name):通过beanName是否为单例对象
  • isPrototype(String name):判断bean对象是否为多例对象
  • isTypeMatch(String name, ResolvableType typeToMatch):判断name值获取出来的bean与typeToMath是否匹配
  • getType(String name):获取Bean的Class类型
  • getAliases(String name):获取name所对应的所有的别名

主要的实现类(包括抽象类):

  • AbstractBeanFactory:抽象Bean工厂,绝大部分的实现类,都是继承于他
  • DefaultListableBeanFactory:Spring默认的工厂类
  • XmlBeanFactory:前期使用XML配置用的比较多的时候用的Bean工厂
  • AbstractXmlApplicationContext:抽象应用容器上下文对象
  • ClassPathXmlApplicationContext:XML解析上下文对象,用户创建Bean对象我们早期写Spring的时候用的就是他

使用方式:

  1. 使用ClassPathXmlApplicationContext读取对应的xml文件实例对应上下文对象
ApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"applicationContext.xml"});
BeanFactory factory = (BeanFactory) context;

FactoryBean

该类是SpringIOC容器是创建Bean的一种形式,这种方式创建Bean会有加成方式,融合了简单的工厂设计模式于装饰器模式
* Interface to be implemented by objects used within a {@link BeanFactory} which * are themselves factories for individual objects. If a bean implements this * interface, it is used as a factory for an object to expose, not directly as a * bean instance that will be exposed itself.
有些人就要问了,我直接使用Spring默认方式创建Bean不香么,为啥还要用FactoryBean做啥,在某些情况下,对于实例Bean对象比较复杂的情况下,使用传统方式创建bean会比较复杂,例如(使用xml配置),这样就出现了FactoryBean接口,可以让用户通过实现该接口来自定义该Bean接口的实例化过程。即包装一层,将复杂的初始化过程包装,让调用者无需关系具体实现细节。

方法:

  • T getObject():返回实例
  • Class<?> getObjectType();:返回该装饰对象的Bean的类型
  • default boolean isSingleton():Bean是否为单例

常用类:

  • ProxyFactoryBean :Aop代理Bean
  • GsonFactoryBean:Gson

使用:

  1. Spring XML方式

application.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="demo" class="cn.lonecloud.spring.example.bo.Person">
        <property name="age" value="10"/>
        <property name="name" value="xiaoMing"/>
    </bean>

    <bean id="demoFromFactory" class="cn.lonecloud.spring.example.bean.PersonFactoryBean">
        <property name="initStr" value="10,init from factory"/>
    </bean>
</beans>

personFactoryBean.java

package cn.lonecloud.spring.example.bean;

import cn.lonecloud.spring.example.bo.Person;
import org.springframework.beans.factory.FactoryBean;

import java.util.Objects;

/**
 * TODO
 *
 * @author lonecloud <lonecloud@aliyun.com>
 * @date 2020/8/24 16:00
 * @since v1.0
 */
public class PersonFactoryBean implements FactoryBean<Person> {

    /**
     * 初始化Str
     */
    private String initStr;

    @Override
    public Person getObject() throws Exception {
        //这里我需要获取对应参数
        Objects.requireNonNull(initStr);
        String[] split = initStr.split(",");
        Person p=new Person();
        p.setAge(Integer.parseInt(split[0]));
        p.setName(split[1]);
        //这里可能需要还要有其他复杂事情需要处理
        return p;
    }

    @Override
    public Class<?> getObjectType() {
        return Person.class;
    }

    public String getInitStr() {
        return initStr;
    }

    public void setInitStr(String initStr) {
        this.initStr = initStr;
    }
}

main方法

package cn.lonecloud.spring.example.factory;

import cn.lonecloud.spring.example.bo.Person;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * BeanFactory 例子
 *
 * @author lonecloud <lonecloud@aliyun.com>
 * @date 2020/8/24 16:00
 * @since v1.0
 */
public class SpringBeanFactoryMain {

    public static void main(String[] args) {
        //这个是BeanFactory
        BeanFactory beanFactory = new ClassPathXmlApplicationContext("application.xml");
        //获取对应的对象化
        Object demo = beanFactory.getBean("demo");
        System.out.println(demo instanceof Person);
        System.out.println(demo);
        //获取从工厂Bean中获取对象
        Person demoFromFactory = beanFactory.getBean("demoFromFactory", Person.class);
        System.out.println(demoFromFactory);
        //获取对应的personFactory
        Object bean = beanFactory.getBean("&demoFromFactory");
        System.out.println(bean instanceof PersonFactoryBean);
        PersonFactoryBean factoryBean=(PersonFactoryBean) bean;
        System.out.println("初始化参数为:"+factoryBean.getInitStr());
    }
}

输出

true
Person{name='xiaoMing', age=10}
Person{name='init from factory', age=10}
true
初始化参数为:10,init from factory

区别

  1. BeanFactory:负责生产和管理Bean的一个工厂接口,提供一个Spring Ioc容器规范,
  2. FactoryBean: 一种Bean创建的一种方式,对Bean的一种扩展。对于复杂的Bean对象初始化创建使用其可封装对象的创建细节。
<think>嗯,用户想了解Spring中的BeanFactoryFactoryBean区别用法。我需要仔细分析这两个概念的不同点。首先,BeanFactory是IoC容器的基础接口,负责管理获取Bean实例。而FactoryBean本身是一个Bean,但它的作用是创建其他Bean。这点可能容易混淆,因为它们名字相似。 根据引用[1],BeanFactory是生产Bean的工厂,所有Bean都由它管理。而引用[2]提到FactoryBean是一个特殊的Bean,用于生成或修饰对象,类似工厂模式。需要区分两者的角色:一个是容器本身,另一个是容器中的特殊Bean。 用户可能需要具体的例子来理解它们的用法。比如BeanFactory通过getBean()方法获取Bean,而FactoryBean需要实现getObject()来返回目标Bean。引用[3]指出FactoryBean像是中间人,提供其他Bean。例如,ProxyFactoryBean生成代理对象。 还要注意它们的应用场景。BeanFactory是核心容器,而FactoryBean用于复杂对象的创建,如整合第三方库或动态代理。引用[4]总结了两者的功能差异,BeanFactory提供基础管理,FactoryBean允许自定义创建逻辑。 用户可能还关心如何在实际开发中使用它们。例如,配置FactoryBean时,实际获取的是getObject()返回的对象,而不是FactoryBean本身。需要强调这点,避免误解。 最后,总结区别时,分点说明类型、功能、使用方式应用场景会更清晰。确保回答结构符合用户要求,使用中文,行内公式正确,并生成相关问题。</think>### BeanFactoryFactoryBean区别及用法解析 #### 一、核心区别 1. **类型与角色** - **BeanFactory** 是 Spring 的 **IoC 容器核心接口**,用于管理获取 Bean 实例。所有 Spring Bean 的生命周期均由它控制[^1]。 - **FactoryBean** 是一个特殊的 **Bean 类型**,本身作为容器中的 Bean 存在,但其核心功能是 **生产其他 Bean 实例**(例如代理对象或复杂对象)[^2]。 2. **功能对比** | 特性 | BeanFactory | FactoryBean | |---------------------|------------------------------|---------------------------------| | 定位 | Spring 容器的根接口 | 用于生成复杂对象的特殊 Bean | | 直接作用 | 管理所有 Bean 的注册与依赖注入 | 自定义生成特定类型的 Bean | | 获取对象方式 | 通过 `getBean("beanName")` | 通过 `FactoryBean.getObject()` | | 典型实现类 | `DefaultListableBeanFactory` | `ProxyFactoryBean`, `SqlSessionFactoryBean` | #### 二、具体用法示例 1. **BeanFactory 的典型使用** ```java // 创建容器 BeanFactory factory = new ClassPathXmlApplicationContext("applicationContext.xml"); // 获取 Bean 实例 UserService userService = factory.getBean("userService", UserService.class); ``` 2. **FactoryBean 的实现** ```java public class MyFactoryBean implements FactoryBean<MyObject> { @Override public MyObject getObject() { return new MyObject(); // 自定义创建逻辑 } @Override public Class<?> getObjectType() { return MyObject.class; } @Override public boolean isSingleton() { return true; } } ``` XML 配置: ```xml <bean id="myFactoryBean" class="com.example.MyFactoryBean"/> ``` 实际获取时: ```java // 获取的是 MyObject 实例,而非 MyFactoryBean 本身 MyObject obj = context.getBean("myFactoryBean"); ``` #### 三、应用场景对比 - **BeanFactory** 的应用场景: - 基础容器的初始化与 Bean 管理 - 实现延迟加载(Lazy Initialization) - 多级容器架构中的父/子容器设计[^4] - **FactoryBean** 的典型场景: - 集成第三方库(如 MyBatis 的 `SqlSessionFactoryBean`) - 生成动态代理对象(AOP 场景) - 封装复杂对象构建过程(如连接池配置) #### 四、关键注意事项 1. **FactoryBean 的特殊获取** 若需要获取 `FactoryBean` 本身而非其生产的对象,需在 Bean 名称前加 `&` 符号: ```java FactoryBean<?> factoryBean = context.getBean("&myFactoryBean"); ``` 2. **设计模式映射** `BeanFactory` 体现 **工厂模式**(统一管理对象),`FactoryBean` 更接近 **抽象工厂模式**(生产系列化对象)[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值