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();
    }
相关推荐
向哆哆1 小时前
基于Java的分布式系统架构设计与实现
java·开发语言
付宇轩2 小时前
leetcode 3271.哈希表分割字符串
java·开发语言·算法
Zaralike2 小时前
SpringBoot项目练习
java·开发语言
Clank的游戏栈2 小时前
Unity进阶教程AOI算法原理详解
java·unity·游戏引擎
元亓亓亓2 小时前
java后端开发day14--之前练习的总结和思考
java·开发语言
iamphp2 小时前
数据库-嵌入SQL访问接口
java·数据库·sql
Abelard_2 小时前
Maven在idea中的使用
java·maven
北执南念3 小时前
Spring Boot 中的日志配置
java·spring boot·mybatis
LUCIAZZZ3 小时前
@Transational事务注解底层原理以及什么场景事务会失效
java·数据库·spring boot·mysql·spring·springcloud