技术博客 技术博客
  • JAVA
  • 仓颉
  • 设计模式
  • 人工智能
  • Spring
  • Mybatis
  • Maven
  • Git
  • Kafka
  • RabbitMQ
  • RocketMQ
  • Redis
  • Zookeeper
  • Nginx
  • 数据库套件
  • MySQL
  • Elasticsearch
  • MongoDB
  • Hadoop
  • ClickHouse
  • Hbase
  • Hive
  • Flink
  • Flume
  • SQLite
  • linux
  • Docker
  • Jenkins
  • Kubernetes
  • 工具
  • 前端
  • AI
GitHub (opens new window)
  • JAVA
  • 仓颉
  • 设计模式
  • 人工智能
  • Spring
  • Mybatis
  • Maven
  • Git
  • Kafka
  • RabbitMQ
  • RocketMQ
  • Redis
  • Zookeeper
  • Nginx
  • 数据库套件
  • MySQL
  • Elasticsearch
  • MongoDB
  • Hadoop
  • ClickHouse
  • Hbase
  • Hive
  • Flink
  • Flume
  • SQLite
  • linux
  • Docker
  • Jenkins
  • Kubernetes
  • 工具
  • 前端
  • AI
GitHub (opens new window)
  • Spring

    • spring

      • 核心内容拆解 IOC
      • 核心内容拆解 AOP
      • 核心内容拆解 事件通知
      • 核心内容拆解 三级缓存
      • 核心内容拆解 FactoryBean
      • 注解替代Spring生命周期实现类
    • spring mv

      • Spring MVC 之基本工作原理
    • spring boot

      • SpringBoot 之 Filter、Interceptor、Aspect
      • SpringBoot 之 Starter
      • SpringBoot 之 Stomp 使用和 vue 相配置
      • SpringBoot MyBatisPlus 实现多数据源
      • SpringBoot MyBatis 动态建表
      • Spring Boot 集成 Jasypt 3.0.3 配置文件加密
      • Spring Boot 集成 FastDFS
      • Spring Boot VUE前后端加解密
      • Spring Boot logback.xml 配置
      • Spring Boot MinIO
      • Spring Boot kafka
      • Spring Boot WebSocket
    • spring cloud

      • SpringCloud - Ribbon和Feign
      • SpringCloud alibaba - Nacos
      • SpringCloud alibaba - Sentinel哨兵
      • SpringCloud alibaba - Gateway
      • SpringCloud alibaba - 链路跟踪
      • SpringCloud - 分布式事务一(XA,2PC,3PC)
      • SpringCloud - 分布式事务二(Seata-AT,TCC,Saga)
      • SpringCloud - 分布式事务三(Seata搭建)
      • SpringCloud - 分布式事务四(多数据源事务)
      • SpringCloud - 分布式事务五(微服务间调用的事务处理)
  • Mybatis

    • 核心功能拆解 工作流程
    • 核心功能拆解 Plugin插件功能实现
    • 核心功能拆解 一二级缓存原理
    • MyBatis Plus+Spring Boot 实现一二级缓存以及自定义缓存
  • maven

    • pom 文件介绍及 parent、properties 标签详解
    • dependencies 标签详解
    • 使用 Nexus3.x 搭建私服
  • git

    • 私有 git 仓库搭建

核心内容拆解 FactoryBean

FactoryBean 接口,使得我们可以通过编写自定义代码来实现 Bean 的实例化和注入。具体来说,通过实现 FactoryBean 接口,我们可以在 getObject () 方法中编写自己的逻辑来实例化 Bean,同时可以在 getObjectType () 方法中指定返回的类型。因此,FactoryBean 的主要作用是对 Bean 的创建过程进行个性化定制,使得我们能够更好地控制 Spring 容器中 Bean 的生命周期和行为。同时,它还可以支持单例模式或者原型模式的 Bean 创建方式,更进一步增强了 Spring 容器的灵活性。

public interface FactoryBean<T> {
    // 获取对象
    T getObject() throws Exception;
    // 获取对象类型
    Class<?> getObjectType();
    // 判断是否单例
    boolean isSingleton();
}
1
2
3
4
5
6
7
8

在 《核心功能拆解 IOC》 一文中,当一个 Bean 对象的创建结束,并得到所创建的 Bean 后,会继续执行 getObjectForBeanInstance 方法

   protected <T> T doGetBean(final String name, final Object[] args) {
        // 从缓存中获取实例
        Object sharedInstance = getSingleton(name);
        if (sharedInstance != null) {
            // 如果实现了 FactoryBean,则需要调用 FactoryBean#getObject
            return (T) getObjectForBeanInstance(sharedInstance, name);
        }
        // 从BeanDefinition列表中获取对象
        BeanDefinition beanDefinition = getBeanDefinition(name);
        Object bean = createBean(name, beanDefinition, args);
        // 如果实现了 FactoryBean,则需要调用 FactoryBean#getObject
        return (T) getObjectForBeanInstance(bean, name);
    }
1
2
3
4
5
6
7
8
9
10
11
12
13

该方法用于判断一个 Bean 是否实现了 FactoryBean 接口,如果实现了接口则需要进行对应的操作

private Object getObjectForBeanInstance(Object beanInstance, String beanName) {
    if (!(beanInstance instanceof FactoryBean)) {
        return beanInstance;
    }
    // 查询 Bean 是否已被执行过
    Object object = getCachedObjectForFactoryBean(beanName);
    if (object == null) {
        // 转成 FactoryBean
        FactoryBean<?> factoryBean = (FactoryBean<?>) beanInstance;
        // 具体执行
        object = getObjectFromFactoryBean(factoryBean, beanName);
    }
    return object;
}

protected Object getObjectFromFactoryBean(FactoryBean factory, String beanName) {
    // 判断是否单例,单例会添加到 factoryBeanObjectCache 改该Map中,避免重复
    if (factory.isSingleton()) {
        // 获取
        Object object = this.factoryBeanObjectCache.get(beanName);
        // 判断是否存在
        if (object == null) {
            // 执行
            object = doGetObjectFromFactoryBean(factory, beanName);
            this.factoryBeanObjectCache.put(beanName, (object != null ? object : NULL_OBJECT));
        }
        return (object != NULL_OBJECT ? object : null);
    } else {
        return doGetObjectFromFactoryBean(factory, beanName);
    }
}

private Object doGetObjectFromFactoryBean(final FactoryBean factory, final String beanName){
    try {
        // 调用接口方法
        return factory.getObject();
    } catch (Exception e) {
        throw new BeansException("FactoryBean threw exception on object[" + beanName + "] creation", e);
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40

这种方式可以理解为,实现 FactoryBean 的类是一个代理类,他的工作主要是在自己被创建的时候,按照 Spring 的生命周期,创建自己的实例,填充属性,初始化之前执行,初始化执行,初始化之后执行,这一切都只是为被代理类做好条件铺设,等这个代理类创建完毕后,会执行 getObjectForBeanInstance 方法,返回被代理的类。更简单的理解就是 FactoryBean 可以帮我们制造我们想要的 Bean,供其他 Bean 依赖或使用。

上次更新: 6/11/2025, 4:10:30 PM
核心内容拆解 三级缓存
注解替代Spring生命周期实现类

← 核心内容拆解 三级缓存 注解替代Spring生命周期实现类→

Theme by Vdoing | Copyright © 2023-2025
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式