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();
    }
相关推荐
程序员张31 小时前
Maven编译和打包插件
java·spring boot·maven
ybq195133454312 小时前
Redis-主从复制-分布式系统
java·数据库·redis
weixin_472339463 小时前
高效处理大体积Excel文件的Java技术方案解析
java·开发语言·excel
小毛驴8503 小时前
Linux 后台启动java jar 程序 nohup java -jar
java·linux·jar
DKPT4 小时前
Java桥接模式实现方式与测试方法
java·笔记·学习·设计模式·桥接模式
好奇的菜鸟5 小时前
如何在IntelliJ IDEA中设置数据库连接全局共享
java·数据库·intellij-idea
DuelCode6 小时前
Windows VMWare Centos Docker部署Springboot 应用实现文件上传返回文件http链接
java·spring boot·mysql·nginx·docker·centos·mybatis
优创学社26 小时前
基于springboot的社区生鲜团购系统
java·spring boot·后端
幽络源小助理6 小时前
SpringBoot基于Mysql的商业辅助决策系统设计与实现
java·vue.js·spring boot·后端·mysql·spring
猴哥源码6 小时前
基于Java+springboot 的车险理赔信息管理系统
java·spring boot