3分钟了解FactoryBean的作用和底层工作原理

简介: FactoryBean是Spring框架中的一个接口,用于创建和管理其他Bean实例的对象。FactoryBean的底层工作原理是通过实现FactoryBean接口并实现其中的方FactoryBean是Spring框架中的一个接口,用于创建和管理其他Bean实例的对象。FactoryBean的底层工作原理是通过实现FactoryBean接口并实现其中的方法来创建和管理Bean实例。以下是FactoryBean的代码注释和解释:法来创建和管理Bean实例。以下是FactoryBean的代码注释和解释:

大家好,我是冰点,本节我们通过对FactoryBean 接口源码解析,以及使用示例剖析,让大家3分钟了解FactoryBean的作用和底层工作原理。以及FactoryBean的使用场景,学以致用。


edae31dfe9ae4225916717b50e7725fa.png

FactoryBean是Spring框架中的一个接口,用于创建和管理其他Bean实例的对象。FactoryBean的底层工作原理是通过实现FactoryBean接口并实现其中的方法来创建和管理Bean实例。

以下是FactoryBean的代码注释和解释:

1. FactoryBean 接口源码解析

public interface FactoryBean<T> {
    // 获取由此工厂创建的对象实例
    T getObject() throws Exception;
    // 获取由此工厂创建的对象实例的类型
    Class<?> getObjectType();
    // 判断由此工厂创建的对象实例是否为单例模式
    default boolean isSingleton() {
        return true;
    }
}

getObject()方法:获取由此工厂创建的对象实例,可以在此方法中编写自定义的创建逻辑,例如从外部资源获取对象实例。

getObjectType()方法:获取由此工厂创建的对象实例的类型,Spring框架可以利用此方法来确定依赖注入时需要注入的具体类型。

isSingleton()方法:判断由此工厂创建的对象实例是否为单例模式。默认情况下,FactoryBean创建的对象实例是单例模式,但是可以通过覆盖此方法来改变对象实例的作用域。

2. FactoryBean 使用代码示例

一个简单的FactoryBean示例代码,咱们创建一个随机数生成器的实例:

import java.util.Random;
import org.springframework.beans.factory.FactoryBean;
public class RandomNumberFactoryBean implements FactoryBean<Random> {
    private int seed;
    public void setSeed(int seed) {
        this.seed = seed;
    }
    @Override
    public Random getObject() throws Exception {
        return new Random(seed);
    }
    @Override
    public Class<?> getObjectType() {
        return Random.class;
    }
    @Override
    public boolean isSingleton() {
        return true;
    }
}

RandomNumberFactoryBean实现了FactoryBean接口,并实现了getObject()、getObjectType()和isSingleton()方法。

在getObject()方法中,它返回了一个由seed属性指定的随机数生成器的实例。在getObjectType()方法中,它返回了该实例的类型,即Random类。在isSingleton()方法中,它指定了该实例是一个单例模式的Bean。

要使用注解方式实例化RandomNumberFactoryBean,可以使用@Configuration和@Bean注解。


首先,创建一个配置类,使用@Configuration注解标记该类为配置类。然后,在该类中创建一个用于实例化RandomNumberFactoryBean的@Bean方法,如下所示:

import java.util.Random;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class AppConfig {
    @Bean
    public RandomNumberFactoryBean myRandom() {
        RandomNumberFactoryBean factoryBean = new RandomNumberFactoryBean();
        factoryBean.setSeed(12345);
        return factoryBean;
    }
}

在这个示例中,AppConfig类使用@Configuration注解标记为配置类。然后,它定义了一个名为myRandom的@Bean方法,该方法返回一个RandomNumberFactoryBean实例,并为其设置seed属性值为12345。


最后,在Spring应用程序中,使用AnnotationConfigApplicationContext类来加载该配置类,如下所示:

import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class MyApp {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
        Random random = context.getBean("myRandom", Random.class);
        int number = random.nextInt();
        System.out.println("Random number: " + number);
        context.close();
    }
}

在这个示例中,MyApp类使用AnnotationConfigApplicationContext类来加载AppConfig配置类,并从容器中获取myRandom Bean实例。然后,它使用该实例生成一个随机数,并将其输出到控制台。


使用注解方式实例化RandomNumberFactoryBean与使用XML配置方式实例化它的区别在于,我们可以在@Bean方法中直接创建RandomNumberFactoryBean实例,并为其设置属性值,而不需要使用XML配置文件。这种方式更加便捷和灵活,可以更方便地进行测试和修改。

3. 核心几个点

当Spring容器启动时,它会扫描应用程序中的所有Bean定义,并实例化那些需要实例化的Bean。如果遇到实现了FactoryBean接口的Bean定义,Spring将会为该Bean创建一个特殊的代理对象,以便在需要时调用FactoryBean的方法来创建实际的Bean实例。


当需要使用由FactoryBean创建的Bean时,Spring将会调用代理对象的getObject()方法来获取实际的Bean实例。如果需要,Spring还可以调用代理对象的getObjectType()方法来确定实际Bean实例的类型。


如果FactoryBean创建的Bean是单例模式,那么Spring将在第一次调用getObject()方法时创建实例,并将其缓存起来。以后每次调用getObject()方法时,都会返回同一个实例。如果FactoryBean创建的Bean不是单例模式,则每次调用getObject()方法时都会创建一个新的实例。

 

4. FactoryBean 到底能干什么

FactoryBean允许我们在创建Bean实例时编写自定义的逻辑,并且可以通过其返回的实际Bean实例类型来实现更精细的依赖注入。同时,Spring框架还提供了一些内置的FactoryBean实现,例如ProxyFactoryBean和JndiObjectFactoryBean,可以帮助我们更方便地创建一些常见的Bean实例。


基本上三分钟差不多了,希望对大家有所帮助,如果有问题可以评论区或者私信留言。以上就是今天总结的所有内容,谢谢大家阅读。

目录
相关文章
|
Rust 物联网 人机交互
一文看懂蓝牙在物联网中的应用场景
蓝牙作为一项发明于上世纪的近距离无线通信技术,在手机,电脑领域已经有了充分地基础,那么这项技术在物联网领域又会有哪些应用场景呢?
一文看懂蓝牙在物联网中的应用场景
|
Java 数据库连接 mybatis
MyBatis中对象映射关联之association使用实践
MyBatis中对象映射关联之association使用实践
838 1
|
人工智能 云栖大会
2024云栖大会,我们来了!
2024云栖大会亮点介绍
478 1
|
架构师 算法 Java
阿里年薪百万的P7架构师简历都长什么样?他们都是怎么学习的?
我有一个朋友最近想从一个中型企业跳槽到大厂,目标瞄准了美团、滴滴、字节跳动等大厂,但投了简历,都石沉大海了!
IDEA中返回上一步和下一步快捷键失效【Ctrl+Alt+左箭头】
这篇文章提供了解决IntelliJ IDEA中"返回上一步"和"下一步"快捷键失效的方法,通常是因为与其他软件的快捷键发生冲突,解决方法是更改快捷键设置。
|
编译器 调度
FreeRTOS任务的创建(动态方法和静态方法)
FreeRTOS任务的创建(动态方法和静态方法)
2344 0
|
存储 机器学习/深度学习 异构计算
Transformers 4.37 中文文档(十九)(8)
Transformers 4.37 中文文档(十九)
621 2
|
机器学习/深度学习 人工智能 自然语言处理
揭秘未来:量子计算与人工智能的融合之路
本文旨在探讨量子计算和人工智能(AI)的结合前景及其对科技领域的潜在影响。通过分析当前技术发展态势,揭示两者融合所带来的创新机遇与挑战,并预测其对未来社会变革的可能贡献。文章将深入剖析量子计算在解决复杂问题方面的优势,以及AI在模式识别和数据分析方面的专长,进而展望两者结合在未来技术革新中的关键作用。
|
存储 缓存 NoSQL
数据缓存,可以尝试用RocksDB了
`shigen`,一个专注于Java、Python、Vue和Shell的博主,探讨了为何在学习阿里云DRM产品时选择RocksDB而非Redis或Guava。RocksDB是一个高速、可配置的存储系统,适用于Flash和HDFS,支持数据压缩。与Redis相比,RocksDB在高速存储和灵活性上更具优势。在尝试使用RocksDB与SpringBoot集成时遇到问题,目前尚未解决。他还对比了RocksDB、Redis和Guava Cache的特性,强调RocksDB适合大规模、高性能场景,而Redis适合内存存储和实时性需求。
352 0
数据缓存,可以尝试用RocksDB了
|
存储 SQL 运维
亿级异构任务调度框架设计与实践
阿里云日志服务作为云原生可观测与分析平台。提供了一站式的数据采集、加工、查询分析、可视化、告警、消费与投递等功能。全面提升用户的研发、运维、运营、安全场景的数字化能力。 日志服务平台作为可观测性平台提供了数据导入、数据加工、聚集加工、告警、智能巡检、导出等功能,这些功能在日志服务被称为任务,并且具有大规模的应用,接下来主要介绍下这些任务的调度框架的设计与实践。
1835 0
亿级异构任务调度框架设计与实践