Spring BeanFactory 和 FactoryBean,有什么区别?

开发
本文我们了解了BeanFactory和FactoryBean的基本概念,了解了它们之间的关系,以及在实际应用中的应用场景。

在 Spring框架中,BeanFactory是什么?FactoryBean又是什么?两个很相近的单词,它们之间有什么关联呢?这篇文章,我们来聊一聊。

1. BeanFactory

BeanFactory是 Spring的核心接口之一,代表了 Spring的 IoC(控制反转)容器。它负责管理和配置应用程序中的 Bean,包括 Bean的生命周期、依赖关系和作用域。

如下图是BeanFactory的源码:

BeanFactory的主要方法:

public interface BeanFactory {
    String FACTORY_BEAN_PREFIX = "&";
    Object getBean(String name) throws BeansException;
    <T> T getBean(String name, Class<T> requiredType) throws BeansException;
    Object getBean(String name, Object... args) throws BeansException;
    <T> T getBean(Class<T> requiredType) throws BeansException;
    <T> T getBean(Class<T> requiredType, Object... args) throws BeansException;
    <T> ObjectProvider<T> getBeanProvider(Class<T> requiredType);
    <T> ObjectProvider<T> getBeanProvider(ResolvableType requiredType);
    boolean containsBean(String name);
    boolean isSingleton(String name) throws NoSuchBeanDefinitionException;
    boolean isPrototype(String name) throws NoSuchBeanDefinitionException;
    boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException;
    boolean isTypeMatch(String name, Class<?> typeToMatch) throws NoSuchBeanDefinitionException;
    @Nullable
    Class<?> getType(String name) throws NoSuchBeanDefinitionException;
    @Nullable
    Class<?> getType(String name, boolean allowFactoryBeanInit) throws NoSuchBeanDefinitionException;
    String[] getAliases(String name);
}

BeanFactory的主要特点:

  • 基础容器: BeanFactory是Spring容器的最基础实现,提供了最基本的Bean管理功能。
  • 延迟加载(Lazy Initialization): 默认情况下,BeanFactory在请求Bean时才会创建它,因此适合资源占用较少的场景。
  • 轻量级: 由于功能相对简单,BeanFactory适用于资源受限的环境,如移动设备或嵌入式系统。
  • 核心接口: 它是多个Spring容器实现(如XmlBeanFactory、ClasspathXmlApplicationContext等)的父接口。

使用示例:

BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("beans.xml"));
MyBean myBean = beanFactory.getBean("myBean", MyBean.class);

在实际开发中,ApplicationContext(BeanFactory的子接口)更常用,因为它提供了更多的功能,如事件传播、国际化支持和 Bean后处理等。

2. FactoryBean

FactoryBean也是 Spring 提供的一个接口,用于自定义复杂对象的创建逻辑。通过实现FactoryBean接口,开发者可以控制 Bean实例的创建过程,动态生成 Bean或在创建过程中进行额外的处理。

如下图是FactoryBean的源码:

FactoryBean的主要特点:

  • 自定义实例化逻辑: 允许开发者定义复杂的实例化过程,生成特定类型的Bean。
  • 代理对象创建: 常用于创建代理对象,如AOP中的代理。
  • 返回其他Bean: FactoryBean的getObject()方法可以返回任何对象,而不仅仅是FactoryBean本身。

FactoryBean的关键方法:

  • Object getObject() throws Exception;:返回由FactoryBean创建的对象。
  • Class<?> getObjectType();:返回创建对象的类型。
  • boolean isSingleton();:指示由getObject()创建的对象是否为单例。

使用示例:

如下示例,假设需要创建一个复杂的服务对象,可以通过实现FactoryBean来定制实例化过程。

public class MyServiceFactoryBean implements FactoryBean<MyService> {

    @Override
    public MyService getObject() throws Exception {
        // 自定义创建逻辑
        MyService service = new MyService();
        service.initialize();
        return service;
    }

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

    @Override
    public boolean isSingleton() {
        returntrue;
    }
}

在Spring配置中声明:

<bean id="myService" class="com.example.MyServiceFactoryBean"/>

获取MyService实例:

MyService myService = context.getBean("myService", MyService.class);

3. 两者区别

特性

BeanFactory

FactoryBean

定义

Spring IoC容器的核心接口,用于管理和配置应用程序中的Bean。

一个Spring接口,允许开发者自定义Bean的创建逻辑,作为Bean的工厂。

角色

作为容器,负责加载、配置和管理所有的Bean。

作为Bean的一种特殊类型,用于生成其他Bean实例。

功能

提供Bean的基本管理功能,如依赖注入、生命周期管理等。

提供自定义的Bean实例化过程,可以创建复杂或动态的Bean对象。

使用场景

适用于基本的Bean管理需求,但在实际开发中通常使用更高级的ApplicationContext。

需要复杂对象创建逻辑、创建代理对象或动态生成Bean时使用。

实例类型

通常通过Spring提供的具体实现类,如XmlBeanFactory(已过时)、ClassPathXmlApplicationContext等。

任意实现了FactoryBean接口的类。

获取Bean实例

直接通过容器的getBean方法获取Bean实例。

通过getObject()方法由容器间接获取Bean实例。意味着在Spring配置中声明的FactoryBean会返回其getObject()方法所生成的对象,而不是FactoryBean本身。

4. 总结

本文,我们了解了BeanFactory和FactoryBean的基本概念,了解了它们之间的关系,以及在实际应用中的应用场景。

BeanFactory 是Spring IoC容器的核心接口,负责管理和提供Bean实例,是整个Bean管理机制的基础。

FactoryBean 则是一个用于定制 Bean创建过程的机制,通过实现该接口,可以控制 Bean的实例化、配置甚至返回不同类型的对象。

责任编辑:赵宁宁 来源: 猿java
相关推荐

2023-07-06 14:24:23

Spring接口自定义

2021-05-10 08:01:12

BeanFactoryFactoryBean容器

2023-10-27 07:39:44

IOC容器Spring

2023-10-16 08:16:31

Bean接口类型

2020-03-09 20:56:19

LoRaLoRaWAN无线技术

2022-09-07 18:32:57

并发编程线程

2020-11-09 14:07:53

PyQtQt编程

2022-06-06 14:53:02

LoRaLoRaWAN

2022-09-08 18:38:26

LinuxWindowsmacOS

2022-08-02 08:23:37

SessionCookies

2021-12-17 14:40:02

while(1)for(;;)语言

2024-03-05 18:59:59

前端开发localhost

2021-05-16 14:26:08

RPAIPACIO

2024-09-09 13:10:14

2024-05-27 00:40:00

2022-02-27 15:33:22

安全CASBSASE

2023-12-15 09:21:17

ObjectJavaString

2022-08-31 08:33:54

Bash操作系统Linux

2022-08-22 07:06:32

MyBatisSQL占位符

2021-03-27 10:56:17

promisethenfinally
点赞
收藏

51CTO技术栈公众号