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();
    }
相关推荐
response_L6 分钟前
国产系统统信uos和麒麟v10在线打开word给表格赋值
java·c#·word·信创·在线编辑
苹果酱05676 分钟前
Golang标准库——runtime
java·vue.js·spring boot·mysql·课程设计
User_芊芊君子12 分钟前
【Java】类和对象
java·开发语言
martian66527 分钟前
Spring Boot后端开发全攻略:核心概念与实战指南
java·开发语言·spring boot
跟着珅聪学java2 小时前
spring boot +Elment UI 上传文件教程
java·spring boot·后端·ui·elementui·vue
我命由我123453 小时前
Spring Boot 自定义日志打印(日志级别、logback-spring.xml 文件、自定义日志打印解读)
java·开发语言·jvm·spring boot·spring·java-ee·logback
lilye663 小时前
程序化广告行业(55/89):DMP与DSP对接及数据统计原理剖析
java·服务器·前端
战族狼魂6 小时前
CSGO 皮肤交易平台后端 (Spring Boot) 代码结构与示例
java·spring boot·后端
xyliiiiiL7 小时前
ZGC初步了解
java·jvm·算法
杉之8 小时前
常见前端GET请求以及对应的Spring后端接收接口写法
java·前端·后端·spring·vue