BeanFactory和FactoryBean

文章目录


BeanFactory

BeanFactory 是 Spring 的 IoC(控制反转)容器的基础接口,它提供了管理 Bean 生命周期、依赖注入和配置元数据解析的核心功能。通过 BeanFactory,可以从 Spring 容器中获取 Bean 实例,并且它负责管理这些 Bean 的创建、初始化以及销毁过程。

主要特性

  • 延迟加载:默认情况下,BeanFactory 采用懒加载策略,只有当请求特定的 Bean 时才会创建该 Bean。
  • 轻量级:相比 ApplicationContext,BeanFactory 更加轻量级,适合资源受限环境下的应用。
  • 灵活配置:支持多种配置方式,包括 XML 文件、注解、Java 配置类等。
  • 生命周期管理:提供了一系列回调方法来处理 Bean 的生命周期事件,如初始化前/后、销毁前等。

FactoryBean

FactoryBean 是一个特殊类型的 Bean,它允许你自定义 Bean 的实例化逻辑。实现 FactoryBean 接口的类可以控制如何创建bean对象,而不仅仅是简单地返回一个新实例。这使得你可以更加灵活地定制 Bean 的创建过程,比如返回单例模式的对象、代理对象或者通过复杂逻辑生成的对象。

主要方法

  • Object getObject():返回由 FactoryBean 创建的实际对象实例。这是获取最终 Bean 的入口点。
  • Class<?> getObjectType():返回 getObject() 方法返回的对象类型。
  • boolean isSingleton():指示 FactoryBean 创建的对象是否为单例。如果返回 true,则每次调用 getBean 都会返回同一个实例;否则,每次都会创建新的实例。

代码示例

pom

xml 复制代码
<dependencies>
    <!--spring context依赖:使用的是6.0.0-M2里程碑版-->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>5.3.7</version>
    </dependency>
</dependencies>

实体

java 复制代码
public class B {
    private String name;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}

import com.qf.entity.B;
import org.springframework.beans.factory.FactoryBean;

/**
 * @author qbh
 * @since 2024/11/16 17:25
 */
public class BFactoryBean implements FactoryBean<B> {
    @Override
    public B getObject() throws Exception {
        //可以按照自己想要的方式创建对象
        //如:new、反射、动态代理
        B b = B.class.getDeclaredConstructor().newInstance();
//        B b = new B();
        return b;
    }

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

    @Override
    public boolean isSingleton() {
//        return FactoryBean.super.isSingleton();
        return true;
    }
}

beans.xml

java 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
       
    <bean id="bFactoryBean" class="com.qf.config.BFactoryBean"></bean>
</beans>

测试类

java 复制代码
import com.qf.config.BFactoryBean;
import com.qf.entity.B;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * @author qbh
 * @since 2024/11/16 16:46
 */
public class MyTest {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        //进入Spring源码
        B b2 = (B) context.getBean("bFactoryBean");
        System.out.println();
    }
}

进入ApplicationContext.getBean("bFactoryBean");

java 复制代码
@Override
public Object getBean(String name) throws BeansException {
    assertBeanFactoryActive();
    //进入
    return getBeanFactory().getBean(name);
}

AbstractBeanFactory.getBean(String) → AbstractBeanFactory.doGetBean() → AbstractBeanFactory.getObjectForBeanInstance() → FactoryBeanRegistrySupport.getObjectFromFactoryBean() → doGetObjectFromFactoryBean()

java 复制代码
private Object doGetObjectFromFactoryBean(FactoryBean<?> factory, String beanName) throws BeanCreationException {
    Object object;
    try {
       if (System.getSecurityManager() != null) {
          ...
       }
       else {
          //这里会执行自定义的BFactoryBean.getObject()方法
          object = factory.getObject();
       }
    }
    ...
    return object;
}

注意,自定义FactoryBean的BFactoryBean.getObject()方法是在context.getBean("bFactoryBean")时才开始调用的。

区别与联系

区别

特性 BeanFactory FactoryBean
角色 Spring IoC 容器接口,用于管理 Bean 的生命周期和依赖注入 特殊类型的 Bean,用于自定义 Bean 的实例化逻辑
主要职责 创建、管理和分发 Bean 实例 控制具体 Bean 的创建过程
使用方式 通过getBean()方法从容器中获取 Bean 在配置文件或注解中声明为普通 Bean,但实际行为由其内部逻辑决定
灵活性 提供基本的 Bean 管理功能 提供高度定制化的 Bean 创建能力

联系

  • FactoryBean是在BeanFactory的管理体系下工作的。BeanFactory在创建 bean 时,如果发现某个 bean 是FactoryBean类型,会调用FactoryBean的getObject方法来获取实际的 bean 实例,然后将这个实例纳入自己的管理范围,就像对待普通 bean 一样进行依赖注入、生命周期管理等操作。这意味着FactoryBean是对BeanFactory创建 bean 功能的一种补充和扩展,两者共同协作来实现 Spring 框架中灵活、强大的 bean 管理机制。

  • 两者的最终目的都是为了帮助构建和管理 Spring 应用中的对象(bean),提高应用的可维护性、可扩展性和灵活性。BeanFactory提供了基本的 bean 管理框架,FactoryBean则在这个框架基础上提供了一种创建复杂 bean 的手段,使得开发者可以更方便地处理各种复杂的对象创建需求,共同促进了 Spring 应用的开发和运行。例如,在一个企业级 Spring 应用中,BeanFactory管理着大量的普通 bean,而FactoryBean用于创建一些关键的、需要特殊处理的 bean(如连接池、消息队列等),两者协同工作,确保整个应用的各个组件能够正确地创建、配置和协作。

总结

BeanFactory 是 Spring 容器的基础,提供了 Bean 管理的核心功能;它定义了整个 bean 管理的规范和流程,其他组件(如ApplicationContext等)都是基于BeanFactory构建的,用于提供更高级的功能。

而FactoryBean是在BeanFactory管理的 bean 创建过程中的一个扩展点,它允许开发者通过实现特定的工厂逻辑来定制 bean 的创建过程,丰富了 Spring 容器创建 bean 的方式,但它本身仍然依赖于BeanFactory来管理其生命周期,FactoryBean作为一个普通 bean 被BeanFactory管理,同时又通过getObject方法创建其他 bean(可以理解成私人定制,根据需要完成Bean对象创建过程)。


相关推荐
爱学习的小羊啊44 分钟前
从零开始掌握Spring MVC:深入解析@Controller与@RequestMapping注解的使用
java·spring·mvc
小李不想输啦4 小时前
什么是微服务、微服务如何实现Eureka,网关是什么,nacos是什么
java·spring boot·微服务·eureka·架构
张铁铁是个小胖子4 小时前
微服务学习
java·学习·微服务
ggs_and_ddu4 小时前
Android--java实现手机亮度控制
android·java·智能手机
敲代码娶不了六花5 小时前
jsp | servlet | spring forEach读取不了对象List
java·spring·servlet·tomcat·list·jsp
Yhame.5 小时前
深入理解 Java 中的 ArrayList 和 List:泛型与动态数组
java·开发语言
是小崔啊7 小时前
开源轮子 - EasyExcel02(深入实践)
java·开源·excel
myNameGL7 小时前
linux安装idea
java·ide·intellij-idea
青春男大7 小时前
java栈--数据结构
java·开发语言·数据结构·学习·eclipse
HaiFan.8 小时前
SpringBoot 事务
java·数据库·spring boot·sql·mysql