Spring中BeanFactory与FactoryBean的区别

简单了解Spring中BeanFactory与FactoryBean的区别 主要介绍了简单了解Spring中BeanFactory与FactoryBean的区别,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 立即下载

Spring中BeanFactory与FactoryBean的区别

为了搞明白这个问题,下载了spring源码在本地ide编译调试,debug进去一步步跟踪查看spring的启动流程,运行机制。

之前一直有在小破站看过spring源码的课程,但spring的源码还是太过强大,类库多,各种设计模式灵活运用,有时候一个小的方法跟进去就有好多相关的扩展代码,跟着跟着就偏离了原来的的代码逻辑,方法的调用链很深,幸好看过spring源码的课程讲解,对spring源码的整体启动流程和大体逻辑有所了解,不然看spring源码会懵逼,即便这样,在看debug跟spring源码到具体的一些细节的时候还是会略显吃力,总体来讲还是对spring底层的一些类库和设计的理解有限吧,大体上知道,具体细节到各个具体的类,就还需要再次看代码逻辑

至此,我们切入今天的主题Spring中BeanFactory 和FactoryBean的区别:

先谈谈我个人的理解:

1.这两个类 在spring中都是接口类,属性和方法如下:
在这里插入图片描述

2.由两个接口类的名字和方法可以看出

BeanFactory 是生产Bean实例的一个工厂(Factory),通过这个接口下的方法来获取spring IOC容器中的各种bean实例,在Spring中所有的Bean 都是由 BeanFactory来管理的

FactoryBean 是一个工厂Bean,实际上也是一个Bean 由BeanFactory 创建,只是这个FactoryBean 有点不一样,是一个能生产或修饰对象生成的工厂Bean

个人理解比较浅薄,来抄作业

在网上找找资料总结如下:

一、BeanFactory 接口

beanFactory 接口是spring容器的核心接口,负责:实例化,定位配置应用程序中的对象及建立这些对象间的依赖

spring 提供了多个易用的BeanFactory的实现, 在spring启动中常用的有DefaultListableBeanFactory, AbstractBeanFactory, AbstractAutoCapableBeanFactory

在这里插入图片描述

二、FactoryBean接口

FactoryBean 接口是spring的核心接口,用于编写增强一些逻辑复杂的bean,在bean创建时可以添加逻辑

public interface FactoryBean<T> {
  /**
  * 返回对象的实例
  */
  T getObject() throws Exception;
  /**
  * 返回对象的类型
  */
  Class<?> getObjectType();
  /**
  * 是否是单例
  */   
   boolean isSingleton();
}

简单实现

/**
 * @author xiaolong.ge
 * @since 08 五月 2022
 */
@Component
public class MyFactoryBean implements FactoryBean<UserService> {
    @Override
    public boolean isSingleton() {
        return true;
    }
    @Override
    public UserService getObject() throws Exception {
        System.out.println("MyFactoryBean-->getObject()实例化。。。");
        UserService userService = new UserServiceImpl();
        return userService;
    }
    @Override
    public Class<?> getObjectType() {
        return UserService.class;
    }
}
​
public class AppTest {
    public static void main(String[] args) throws Exception {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(App.class);
        UserService us = (UserService)context.getBean("myFactoryBean");
        System.out.println(us);
        MyFactoryBean myFactoryBean = (MyFactoryBean)context.getBean("&myFactoryBean");
        UserService us2 = myFactoryBean.getObject();
        System.out.println(us2);
        System.out.println(us == us2);
    }
    // 输出结果:
    MyFactoryBean-->getObject()实例化。。。
    com.gexl.service.impl.UserServiceImpl@1440c311
    MyFactoryBean-->getObject()实例化。。。
    com.gexl.service.impl.UserServiceImpl@189b5fb1
    false

增强实现

 /**
 * @author xiaolong.ge
 * @since 08 五月 2022
 */
@Component
public class MyFactoryBean implements FactoryBean<UserService>, InitializingBean, DisposableBean {
​
    private Object proxyObject;
    private Object target;
    private String interfaceName;
​
    public MyFactoryBean() {
        this.interfaceName = UserService.class.getName();
        this.target = new UserServiceImpl();
    }
​
    @Override
    public UserService getObject() throws Exception {
        return (UserService) proxyObject;
    }
​
    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("myFactoryBean afterPropertiesSet..");
        proxyObject = Proxy.newProxyInstance(this.getClass().getClassLoader(), new Class[]{Class.forName(interfaceName)}, new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                System.out.println("方法调用之前增强。。。method="+method.getName());
                Object obj = method.invoke(target,args);
                System.out.println("方法调用之后增强。。。method="+method.getName());
                return obj;
            }
        });
    }
​
    @Override
    public Class<?> getObjectType() {
        return proxyObject == null ? Object.class : proxyObject.getClass();
    }
​
    @Override
    public boolean isSingleton() {
        return true;
    }
​
    @Override
    public void destroy() throws Exception {
        System.out.println("destory...");
    }
    public Object getTarget() {
        return target;
    }
    public void setTarget(Object target) {
        this.target = target;
    }
    public String getInterfaceName() {
        return interfaceName;
    }
    public void setInterfaceName(String interfaceName) {
        this.interfaceName = interfaceName;
    }
}
​
public class AppTest {
   
    @Test
    public void testFactoryBean() throws Exception {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(App.class);
​
        MyFactoryBean myFactoryBean = (MyFactoryBean) context.getBean("&myFactoryBean");
        System.out.println("myFactoryBean="+myFactoryBean);
        UserService userService = myFactoryBean.getObject();
        System.out.println("userService="+userService);
        
        UserServiceImpl targetService = (UserServiceImpl)myFactoryBean.getTarget();
        String beanName = "userDao";
        UserDao userDao = (UserDao)context.getBean(beanName);
        Field field = targetService.getClass().getDeclaredField(beanName);
        field.setAccessible(true);
        field.set(targetService,userDao);
        // 调用方法
        userService.getById(1);
    }
}
    // 输出结果:
    myFactoryBean afterPropertiesSet..
    myFactoryBean=com.gexl.service.impl.MyFactoryBean@65bb9029
    方法调用之前增强。。。method=toString
    方法调用之后增强。。。method=toString
    userService=com.gexl.service.impl.UserServiceImpl@1bfe3203
    方法调用之前增强。。。method=getById
    方法调用之后增强。。。method=getById

应用实例

Spring在整合mybatis框架时 SqlSessionFactoryBean 就是应用的FactoryBean

Spring会调用SqlSessionFactoryBean这个实现了FactoryBean的工厂Bean 同时加载dataSource,Mapper文件的路径,对sqlSessionFactory进行初始化。

public class SqlSessionFactoryBean implements FactoryBean<SqlSessionFactory>, InitializingBean, ApplicationListener<ApplicationEvent> {
 .....
 @Override
 public void afterPropertiesSet() throws Exception {
   notNull(dataSource, "Property 'dataSource' is required");
   notNull(sqlSessionFactoryBuilder, "Property 'sqlSessionFactoryBuilder' is required");
   state((configuration == null && configLocation == null) || !(configuration != null && configLocation != null),
             "Property 'configuration' and 'configLocation' can not specified with together");
   // 创建 sqlSessionFactory 
   this.sqlSessionFactory = buildSqlSessionFactory();
 }

 /**
  * Build a {@code SqlSessionFactory} instance.
  *
  * The default implementation uses the standard MyBatis {@code XMLConfigBuilder} API to build a
  * {@code SqlSessionFactory} instance based on an Reader.
  * Since 1.3.0, it can be specified a {@link Configuration} instance directly(without config file).
  *
  * @return SqlSessionFactory
  * @throws Exception if configuration is failed
  */
 protected SqlSessionFactory buildSqlSessionFactory() throws Exception {
​
   final Configuration targetConfiguration;
   XMLConfigBuilder xmlConfigBuilder = null;
   if (this.configuration != null) {
     targetConfiguration = this.configuration;
     if (targetConfiguration.getVariables() == null) {
       targetConfiguration.setVariables(this.configurationProperties);
     } else if (this.configurationProperties != null) {
       targetConfiguration.getVariables().putAll(this.configurationProperties);
     }
   } else if (this.configLocation != null) {
     xmlConfigBuilder = new XMLConfigBuilder(this.configLocation.getInputStream(), null, this.configurationProperties);
     targetConfiguration = xmlConfigBuilder.getConfiguration();
   } else {
     LOGGER.debug(() -> "Property 'configuration' or 'configLocation' not specified, using default MyBatis Configuration");
     targetConfiguration = new Configuration();
     Optional.ofNullable(this.configurationProperties).ifPresent(targetConfiguration::setVariables);
   }
   ... 省略
   Optional.ofNullable(this.cache).ifPresent(targetConfiguration::addCache);
   ... 省略
   
   if (this.mapperLocations != null) {
     if (this.mapperLocations.length == 0) {
       LOGGER.warn(() -> "Property 'mapperLocations' was specified but matching resources are not found.");
     } else {
       for (Resource mapperLocation : this.mapperLocations) {
         if (mapperLocation == null) {
           continue;
         }
         try {
           XMLMapperBuilder xmlMapperBuilder = new XMLMapperBuilder(mapperLocation.getInputStream(),
               targetConfiguration, mapperLocation.toString(), targetConfiguration.getSqlFragments());
           xmlMapperBuilder.parse();
         } catch (Exception e) {
           throw new NestedIOException("Failed to parse mapping resource: '" + mapperLocation + "'", e);
         } finally {
           ErrorContext.instance().reset();
         }
         LOGGER.debug(() -> "Parsed mapper file: '" + mapperLocation + "'");
       }
     }
   } else {
     LOGGER.debug(() -> "Property 'mapperLocations' was not specified.");
   }
   return this.sqlSessionFactoryBuilder.build(targetConfiguration);
 }
 ...
 }
三、总结

BeanFactory是Spring中IOC容器最核心的接口,遵循了IOC容器中所需的基本接口。比如:ApplicationContext, AbstractBeanFactory等 都使用了BeanFactory接口。

FactoryBean是工厂类接口,只想简单构造Bean,不希望实现原有大量的方法。它是一个Bean,不过这个Bean能够做为工厂去创建Bean, 同时还能修饰对象的生成

FactoryBean比BeanFactory在生产Bean的时候灵活,还能修饰对象,带有工厂模式和装饰模式的意思在里面,不过它的存在还是以Bean的形式存在

电力负荷预测 | 电力系统负荷预测模型(Python线性回归、随机森林、支持向量机、BP神经网络、GRU、LSTM) 阅读详情

相关推荐

ROS 2 Jazzy与Gazebo Harmonic仿真实战:从零搭建机器人仿真环境与高级应用

本文详细介绍了如何使用ROS 2 Jazzy和Gazebo Harmonic从零搭建机器人仿真环境,涵盖环境配置、传感器集成、多机器人协同和GPU加速优化等高级应用。通过实战案例和性能调优技巧,帮助开发者高效构建可靠的机器人仿真系统,提升开发效率。

h9j8k7l6m5n的博客 1219

BeanFactory 简介以及它 和FactoryBean的区别(阿里面试)

BeanFacotry是spring中比较原始的Factory。如XMLBeanFactory就是一种典型的BeanFactory。原始的BeanFactory无法支持spring的许多插件,如AOP功能、Web应用等。ApplicationContext接口,它由BeanFactory接口派生而来,ApplicationContext包含BeanFactory的所有功能,通常建议比B...

2655

SRv6第二弹:SRv6基本概念

在SRv6网络编程中,不同的转发行为由不同的Function来标识,例如在RFC中定义了公认的End、End.X、End.DX4、End.DX6等。例如:R3使用报文的IPv6目的地址FC03::3查找Local SID表,命中到End SID,随后R3将报文SL减1,同时将SL=1的SID做为报文目标IPv6地址,并查路由表转发出去。SID支持静态配置或者动态分配,end-op、end、end.x、end-dt4、end-dt6、end-dx2推荐静态配置 ,便于网络运维,其他的SID可以动态分配。

wbyyy的博客 4251

Spring 中 BeanFactory 与 FactoryBean 的区别

Spring 中 BeanFactory 与 FactoryBean 的区别 直接区别 直面意思:Bean工厂、工厂Bean 1、BeanFactory:以 Factory 结尾,表示它是一个工厂类(接口),用于管理 Bean 的一个工厂。在 Spring 中,BeanFactory 是 IOC 容器的核心接口,它的职责包括:实例化、定位、配置应用程序中的对象及建立这些对象间的依赖。 2、FactoryBean:以 Bean 结尾,表示它是一个 Bean,不同于普通 Bean 的是:它是实现了 Factor

琦彦 1846

Latex参考文献中大写字母编译后自动变成了小写,如何保持原字母大写形式

bib文件参考文献中大写自动变为小写,如何保持原大写问题。Latex: 保持参考文献大小写,overleaf文献编译后,原大写字母自动变成了小写字母,如何保持原字母大写

我的个人博客 5806

海思方案定制hi3531dv200/SS528 DVR方案解析:从硬件选型到编解码实战应用

海思方案,Hi3518EV100,Hi3518CV100,Hi3515CV100,Hi3516CV100,Hi3516ECV100,Hi3516D,Hi3516A,Hi3519,Hi3520D,Hi3521A,Hi3535,Hi3531,Hi3536,Hi3536C,Hi3536D,Hi3518EV200,Hi3518EV201,Hi3520DV200,Hi3516CV200,Hi3516CV300,Hi3516AV200,Hi3520DV300,Hi3519V101,sd3403,hi3519av200

1585

BeanFactory和FactoryBean的区别

BeanFactroy和FactroyBean的区别

赢啦啦的博客 2880

计算机毕设:线性回归 Xgboost LSTM 预测黄金价格实战 完整代码数据视频讲解 可直接运行

线性回归 Xgboost LSTM 预测黄金价格实战 完整代码数据视频讲解 可直接运行

1762

spring中FactoryBean和BeanFactory区别

BeanFactory:是Spring IoC容器的核心接口,用于管理Bean的一个工厂。它定义了IoC容器的最基本形式,并提供了IoC容器应遵守的最基本的接口,也就是Spring IoC所遵守的最底层和最基本的编程规范。BeanFactory的主要职责包括实例化、定位、配置应用程序中的对象及建立这些对象间的依赖。FactoryBean:是一个特殊的Bean,它实现了FactoryBean接口。FactoryBean不仅仅是一个Bean,它更像是一个工厂,用于生成或修饰其他Bean的实例。

sutingStart的博客 1730

从零搭建 C# + YOLO 工业视觉系统:从模型训练到上位机部署(工业级落地)

做工业质检、自动化生产线的同学都懂:一套能用的工业视觉系统,既要“检测准”,又要“界面易操作”,还要“部署稳”。之前帮某电子厂做PCB缺陷检测,一开始用Python+YOLO做检测核心,QT做上位机,结果踩了无数坑:Python推理速度波动大,QT和Python跨语言集成繁琐,数据传递容易卡顿;后来换成C# + YOLO的组合,直接打通了“模型训练-上位机开发-工业部署”全流程——C#的WinForms/WPF开发上位机高效,工业相机SDK支持完善;

这里只有干货:从 Modbus 通信到 MES 对接,从 YOLO 训练到工控机部署,带你搞定工业软件开发全流程。 737

三、参考比较法之城市建成区提取——提取

在正式开始提取之前,还是要继续啰嗦一下,其实基于夜间灯光数据建成区提取,可以分为好几个层次,基于县一级、市一级、省一级,很多论文的做法都是以市一级为准,也就是统计好市一级城市的每一年的统计年鉴中的建成区面积作为备用。有人可能会问为什么不以县一级,由于县一级的统计数据一般存在缺失,很难形成一个长时间序列的数据,所以一般采取的是市一级。前文也进行建议,如果确实要基于县一级进行提取可以参考前面理论介绍那篇文章中的相关建议。那么当我们确定阈值后如何将城市建成区提取出来?

端木宛白的博客家园 5401

spring中BeanFactory和FactoryBean的区别

spring中BeanFactory和FactoryBean的区别

淡淡的幸福的博客 7万+

使用MATLAB和Simulink来设计并仿真一个智能家居多传感器数据融合系统

智能家居多传感器数据融合系统旨在通过集成来自多种不同类型的传感器的数据,以提供更精确和可靠的环境信息或用户状态监测。例如,将温度、湿度、光照强度、运动检测等多种传感器的数据结合起来,可以更好地了解家庭内部的状态,并做出相应的调整或响应。在这个教程中,我们将使用MATLAB和Simulink来设计并仿真一个智能家居多传感器数据融合系统。

amy_mhd的博客 189

Spring FactoryBean和BeanFactory 区别

1 BeanFactory 是ioc容器的底层实现接口,是ApplicationContext 顶级接口 spring不允许我们直接操作 BeanFactory bean工厂,所以为我们提供了ApplicationContext 这个接口 此接口集成BeanFactory 接口,ApplicationContext包含BeanFactory的所有功能,同时还进行更多的扩展。 BeanFactor...

. 1万+

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

Spring BeanFactory 和 FactoryBean区别详解

详细介绍Spring BeanFactory 和 FactoryBean区别

m0_66220639的博客 994

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

【Spring】BeanFactory与FactoryBean的区别

【Spring】BeanFactory与FactoryBean的区别1. BeanFactory1.1 源码1.2 使用场景2. FactoryBean2.1 源码2.2 示例2.3 使用场景3. 区别 1. BeanFactory BeanFactory是一个接口,它是Spring中工厂的顶层规范,是SpringIoc容器的核心接口,它定义了getBean()、containsBean()等管理Bean的通用方法。Spring的容器都是它的具体实现主要有三种如: DefaultListableBeanF

来日浅谈的博客 612

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

Spring BeanFactory与FactoryBean的区别

BeanFactory是spring中比较原始的Factory。它无法支持spring的许多插件,如AOP功能,Web应用等,ApplicationContext接口由Beanfactory接口派生而来,并对其功能进行了扩展。 BeanFactory与FactoryBean的区别: 相同点:都是接口 区别: Beanfactory是一个工厂类,用于管理Bean的一个工厂,在sprin...

曰业而安的博客 1420

【spring】BeanFactory与FactoryBean的区别

文章目录前言一、为什么会有FactoryBean?二、通过源码深入学习FactoryBean总结 前言 经常说spring的核心是ioc,ioc的核心是BeanFactory。然而在spring中还有一个很容易让人混淆的词FactoryBean,很容易让人无法理解。本文通过一些mybatis源码来讲述其区别,请大家参考。 一、为什么会有FactoryBean? BeanFactory是在学习IOC第一课的时候就遇到的。它是生产bean的工厂。在此工厂中,我们可以生产出我们想要的bean,并且通过

叁滴水 的博客 4301

Spring之BeanFactory和FactoryBean接口的区别

文章目录一、BeanFactory接口二、FactoryBean接口1.简单实现2.增强实现3.FactoryBean的实际使用案例三、总结   Spring框架中的BeanFactory接口和FactoryBean接口因为名称相似,老是容易搞混淆,而且也是面试过程中经常会碰到的一个问题。所以本文就专门给大家整理出来。 一、BeanFactory接口   BeanFactory接口是Spring容...

波波烤鸭的博客 6105

Spring中BeanFactory, FactoryBean,ApplicationContext的区别

Spring中BeanFactory, FactoryBean,ApplicationContext的区别

果酱 の 博客 1133

Spring BeanFactory和FactoryBean的区别

目录 一、简介 二、BeanFactory 三、FactoryBean 四、总结 一、简介 在Spring中,有这么2个接口:BeanFactory和FactoryBean,名字很相似,很多小伙伴经常混淆,在面试的时候也经常会被问BeanFactory和FactoryBean两者的区别。本篇文章将详细介绍它们的区别,并结合示例,帮助大家对BeanFactory和FactoryBean有一个很好的认识。 二、BeanFactory BeanFactory是Spring IoC 容器的顶层接口,

weixiaohuai的博客 920

Spring BeanFactory 与 FactoryBean的区别

首先总结一下BeanFactory 与 FactoryBean 的区别 BeanFactroy spring中Bean的工厂,它能够去生产我们的类,并且能够获取我们的对象,比如我们的一个类交给spring去管理,我们可以通过这个BeanFactroy 直接get BeanName出来。 FactroyBean,它是spring中一个特殊的Bean,它是一个接口里面有三个方法需要去实现,实现了F...

@Bean 798

Spring中BeanFactory与FactoryBean到底有什么区别?

一、BeanFactory BeanFactory是一个接口,它是Spring中工厂的顶层规范,是SpringIoc容器的核心接口,它定义了getBean()、containsBean()等管理Bean的通用方法。Spring的容器都是它的具体实现如: DefaultListableBeanFactory XmlBeanFactory ApplicationContext 这些实现类又从不同的维度分别有不同的扩展。 1.1、源码 public interface BeanFactory { //对Fa

weixin_51439578的博客 768

spring中FactoryBean和BeanFactory的区别

目录 一、BeanFactory 1.1 源码 1.2 使用场景 二、FactoryBean 2.1 源码 2.2 示例 2.2.1 方法一 2.2.2 方法二 2.3 FactoryBean的两种用法 2.3.1 简化xml配置,隐藏细节 2.3.2 返回不同Bean的实例 2.4 使用场景 三、BeanFactory和FactoryBean的区别以及共同点 一、BeanFactory BeanFactory,以Factory结尾,表示它是一个工厂类(接口),它负责生..

大叶子不小的博客 892

Spring中关于BeanFactory和FactoryBean的区别

Spring中关于BeanFactory和FactoryBean的区别关于BeanFactory和FactoryBean的简单描述及区别BeanFactory的详细描述:FactoryBean的详细描述:总结 关于BeanFactory和FactoryBean的简单描述及区别 BeanFactory是Spring容器的顶级接⼝,给具体的IOC容器的实现提供了规范。 FactoryBean也是接⼝,为IOC容器中Bean的实现提供了更加灵活的⽅式,FactoryBean在IOC容器的基 础上给Bean的实现加

weixin_45137959的博客 266
上一篇: java类加载机制
下一篇: 配置Springboot支持https和http协议
xiaolong_java
博客等级 码龄12年 1粉丝 11原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值