BeanFactory与factoryBean 区别,请用源码分析,及spring中涉及的点,及应用场景

BeanFactoryFactoryBean 都是 Spring 框架中的核心接口,且有着不同的目的和应用场景。我们可以从源码角度分析它们的区别,并探讨它们的作用和应用场景。

1. BeanFactory

BeanFactory 是 Spring 中最基本的容器接口之一。它定义了 Spring 容器的基本操作方法,比如获取 Bean 对象、初始化 Bean 等。

关键方法
复制代码

java

public interface BeanFactory { Object getBean(String name) throws BeansException; Object getBean(String name, Object... args) throws BeansException; boolean containsBean(String name); boolean isSingleton(String name) throws NoSuchBeanDefinitionException; boolean isPrototype(String name) throws NoSuchBeanDefinitionException; }

功能:
  • BeanFactory 负责根据 Bean 的名称和配置来获取 Bean 实例。
  • 它通过 getBean() 方法来从容器中获取 Bean。
  • 它不负责实例化单例 Bean 直到调用 getBean() 时才实例化,所以它是懒加载的(Lazy Initialization)。
适用场景:
  • 在大多数情况下,我们通常使用 ApplicationContext 来代替 BeanFactory,因为 ApplicationContextBeanFactory 的子接口,并且提供了更多的功能(如国际化、事件传播、AOP 等)。
  • 如果你的应用非常轻量,且只需要基础的 Bean 管理功能,可以使用 BeanFactory

2. FactoryBean

FactoryBean 是 Spring 中的一个接口,它允许开发者控制 Bean 的实例化过程。通过实现 FactoryBean 接口,开发者可以自定义 Bean 的创建逻辑。

关键方法
复制代码

java

public interface FactoryBean<T> { T getObject() throws Exception; Class<?> getObjectType(); boolean isSingleton(); }

功能:
  • getObject():返回一个新的或现有的对象。通过 FactoryBean,你可以创建复杂的 Bean 实例,或者返回非标准的对象类型。
  • getObjectType():返回该 FactoryBean 创建的对象的类型。
  • isSingleton():如果这个 FactoryBean 创建的对象是单例的,则返回 true;否则返回 false
适用场景:
  • 当你需要自定义 Bean 的创建逻辑时,使用 FactoryBean 是一个非常好的选择。典型的场景包括:
    • 工厂模式:需要动态地创建不同类型的 Bean。
    • 第三方库的适配 :当你需要将第三方库中的某些对象集成到 Spring 容器中时,可以通过 FactoryBean 来封装其创建过程。
    • 动态代理 :如果需要在 Spring 容器中管理动态代理对象,可以通过 FactoryBean 进行创建。

3. BeanFactory 与 FactoryBean 的区别

特性 BeanFactory FactoryBean
目的 管理 Spring 容器中的所有 Bean 自定义 Bean 的创建过程
主要功能 获取 Bean、管理 Bean 生命周期 创建特定的 Bean 实例,控制 Bean 的初始化逻辑
实现方式 通过 getBean() 获取 Bean 通过 getObject() 创建 Bean,通常与工厂模式结合使用
使用场景 基本的 Bean 管理与获取 需要自定义 Bean 创建过程时,或者动态 Bean 的情况
是否懒加载 默认是懒加载(对于单例 Bean) 根据 isSingleton() 的实现来决定 Bean 的生命周期

4. Spring 中的应用场景

4.1 BeanFactory 的应用

BeanFactory 一般在 Spring 中并不直接使用,开发者更多的是使用 ApplicationContext。但是,在一些内存或性能特别敏感的应用场景下,BeanFactory 仍然有它的价值。例如,当你只需要非常简单的 Bean 获取功能时,可以通过 BeanFactory 实现更加轻量的容器。

4.2 FactoryBean 的应用
  • 动态代理对象FactoryBean 可以用来创建动态代理。例如,Spring AOP 会使用 FactoryBean 来创建代理对象。
  • 第三方库集成 :某些第三方库的对象可能无法直接作为 Spring Bean 创建。这时可以通过 FactoryBean 来封装这些对象的创建过程,使它们能够被 Spring 容器管理。
  • 复杂 Bean 初始化 :当 Bean 的初始化过程复杂,需要多步处理时,可以使用 FactoryBean 来处理 Bean 的实例化。
示例:FactoryBean 的使用
java 复制代码
public class MyBeanFactory implements FactoryBean<MyBean> {
    
    @Override
    public MyBean getObject() throws Exception {
        return new MyBean();  // 这里是自定义的创建逻辑
    }

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

    @Override
    public boolean isSingleton() {
        return true;  // 如果需要单例,返回 true
    }
}

在配置文件中,使用 FactoryBean 创建 MyBean

<bean id="myBean" class="com.example.MyBeanFactory"/>

总结:

  • BeanFactory 是 Spring 中最基础的容器接口,负责获取和管理 Bean。
  • FactoryBean 是一个工厂接口,允许你自定义 Bean 的创建逻辑,并将其交给 Spring 管理。
  • 使用 BeanFactory 时你只能获取已经存在的 Bean,而使用 FactoryBean 时可以控制 Bean 的创建过程,适用于复杂的初始化或自定义实例化的场景。

通过理解这两个接口的区别,可以帮助开发者在合适的场景下选择合适的接口和方式来管理 Bean 的生命周期和创建。

实际应用场景

BeanFactory

复制代码
<T> T getBean(String var1, Class<T> var2) throws BeansException;
java 复制代码
        String statuseServiceBeanname = STATE_SERVICE_PRE + stateMachineType;
        IStatusService iStatusService = abstractStateMachineEngine.getApplicationContext().getBean(statuseServiceBeanname, IStatusService.class);

FactoryBean - getObject

java 复制代码
    @Bean(name = "mallSqlSessionFactory")
    public SqlSessionFactory mallSqlSessionFactory(@Qualifier("mallDataSource") DataSource dataSource)
            throws Exception {
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(dataSource);
        Interceptor[] plugins =  new Interceptor[]{new PageHelper()};
        bean.setPlugins(plugins);
        bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mybatis/mappers/*.xml"));
        return bean.getObject();
    }
相关推荐
小猪佩奇TONY12 分钟前
Vulkan 学习(12)---- Vulkan pipeline 创建
java·学习·spring
DC_BLOG1 小时前
数据结构排序
java·数据结构·算法·排序算法
Upuping1 小时前
Servlet详解
java·后端·web
华年源码1 小时前
基于springboot的房屋租赁系统(源码+数据库+文档)
java·数据库·spring boot·后端·毕业设计·源码·springboot
Jason-河山1 小时前
如何利用Java爬虫批量获取商品信息
java·开发语言·爬虫
シ風箏1 小时前
Kafka【应用 04】Java实现筛选查询Kafka符合条件的最新数据(保证数据最新+修改map对象key的方法+获取指定数量的记录)源码分享粘贴可用
java·kafka·linq
CodeChampion1 小时前
68.基于SpringBoot + Vue实现的前后端分离-心灵治愈交流平台系统(项目 + 论文PPT)
java·vue.js·spring boot·mysql·elementui·node.js·idea
鲁子狄1 小时前
[笔记] Jenkins 安装与配置全攻略:Ubuntu 从零开始搭建持续集成环境
java·linux·运维·笔记·ubuntu·ci/cd·jenkins
kay5351 小时前
编排式 Saga 模式
java·spring boot
DaXiongJoker1 小时前
解决高并发环境消息通知涉及问题
java·redis·性能优化·kafka·rabbitmq·信息与通信