我的编程空间,编程开发者的网络收藏夹
学习永远不晚

BeanFactory和FactoryBean的区别有哪些

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

BeanFactory和FactoryBean的区别有哪些

BeanFactory和FactoryBean的区别有哪些,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。

BeanFactory和FactoryBean的区别有哪些

区别

说实话,他俩除了名字比较像以外,好像没有其他共同点了。

「BeanFactory和FactoryBean有哪些区别?」

  1. BeanFactory是一个最基础的IOC容器,提供了依赖查找,依赖注入等基础的功能

  2. FactoryBean是创建Bean的一种方式,帮助实现复杂Bean的创建

和BeanFactory相关的还有一个高频的面试题

「ApplicationContext和BeanFactory有哪些区别?」

  1. BeanFactory是一个最基础的IOC容器,提供了依赖查找,依赖注入等基础的功能

  2. ApplicationContext继承了BeanFactory,在BeanFactory的基础上增加了企业级的功能,如AOP,资源管理(Resources)事件(Event),国际化(i18n),Environment抽象等

创建Bean的方式

常见的创建Bean的方式有如下四种

  1. 通过构造器

  2. 通过静态工厂方法

  3. 通过Bean工厂方法

  4. 通过FactoryBean

@Data @ToString public class User {   private Long id;  private String name;   public static User createUser() {   User user = new User();   user.setId(1L);   user.setName("li");   return user;  } }
public class UserFactory {   public User createUser() {   return User.createUser();  } }
public class UserFactoryBean implements FactoryBean {   @Override  public Object getObject() throws Exception {   return User.createUser();  }   @Override  public Class<?> getObjectType() {   return User.class;  } }
<?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         https://www.springframework.org/schema/beans/spring-beans.xsd">   <!-- 构造方法实例化 Bean -->  <bean id="user-by-constructor" class="com.javashitang.domain.User">   <property name="id" value="1"/>         <property name="name" value="li"/>  </bean>   <!-- 静态方法实例化 Bean -->  <bean id="user-by-static-method" class="com.javashitang.domain.User"     factory-method="createUser"/>   <bean id="userFactory" class="com.javashitang.factory.UserFactory"/>   <!-- Bean工厂方法实例化 Bean -->  <bean id="user-by-factory" factory-bean="userFactory" factory-method="createUser"/>   <!-- FactoryBean实例化 Bean -->  <bean id="user-by-factory-bean" class="com.javashitang.factory.UserFactoryBean"/> </beans>
public class BeanInstantiationDemo {   public static void main(String[] args) {   BeanFactory beanFactory = new ClassPathXmlApplicationContext("classpath:/bean-instantiation-context.xml");   User user1 = beanFactory.getBean("user-by-constructor", User.class);   User user2 = beanFactory.getBean("user-by-static-method", User.class);   User user3 = beanFactory.getBean("user-by-factory", User.class);   User user4 = beanFactory.getBean("user-by-factory-bean", User.class);  } }

实现原理

在分析源码之前,我们先明确2个概念

「factoryBean是我们配置到容器中的实现FactoryBean接口的Bean,而subBean是用FactoryBean创建出来的Bean」

在Spring容器启动的过程中,会实例化非延迟的单例Bean,即调用如下方法  DefaultListableBeanFactory#preInstantiateSingletons

BeanFactory和FactoryBean的区别有哪些

调用FactoryBean#getObject的链路如下图

BeanFactory和FactoryBean的区别有哪些

通过分析DefaultListableBeanFactory#preInstantiateSingletons方法和FactoryBean#getObject的调用链路可以分析得到

  1. 单例的factoryBean对象本身会在spring容器启动时主动初始化。而subBean的初始化则是在第一次从缓存中获取factoryBean并且不为空才会触发

  2. 如果factoryBean对象实现的接口是SmartFactoryBean且isEagerInit方法返回true,那么subBean对象也会在spring容器启动的时候主动初始化

  3. 如果bean注册的时候,beanName对应的bean实例是一个factoryBean,那么我们通过getBean(beanName)获取到的对象将会是subBean对象;如果要获取工厂对象factoryBean,需要使用getBean("&"  + beanName)

  4. 单例的subBean也会缓存在spring容器中,具体的容器是FactoryBeanRegistrySupport#factoryBeanObjectCache,一个Map

「建议大家看一下DefaultListableBeanFactory#preInstantiateSingletons方法和FactoryBean#getObject方法的调用链路,就能理解上面我说的流程了,我就不贴太多源码了」

应用

目前我只在Dubbbo源码中看到了FactoryBean的应用

「服务导出:在Dubbo中,服务提供者会被包装成ServiceBean对象,当监听到ContextRefreshedEvent事件时开始服务导出」

「服务调用:服务调用方会被包装成ReferenceBean对象,ReferenceBean实现了FactoryBean接口和InitializingBean接口,创建subBean的逻辑在ReferenceBean#getObject方法中」

「Dubbo服务引入的时机有如下2种。」

  1. 饿汉式:init=true,在Bean生命周期的初始化阶段会调用InitializingBean#afterPropertiesSet方法,而这个方法会调用ReferenceBean#getObject方法,完成subBean的创建,即ReferenceBean实例化时完成服务引入

  2. 懒汉式:init=false,在ReferenceBean对应的服务被注入到其他类中时,此时会调用AbstractApplicationContext#getBean,获取ReferenceBean对象,因为ReferenceBean实现了FactoryBean接口,所以会调用ReferenceBean#getObject方法,完成subBean的创建,即完成服务引入

public class ReferenceBean<T> extends ReferenceConfig<T> implements FactoryBean, ApplicationContextAware, InitializingBean, DisposableBean {      @Override     public Object getObject() {         return get();     }      @Override     @SuppressWarnings({"unchecked"})     public void afterPropertiesSet() throws Exception {          // 省略部分代码          if (shouldInit()) {             getObject();         }     }      }

关于BeanFactory和FactoryBean的区别有哪些问题的解答就分享到这里了,希望以上内容可以对大家有一定的帮助,如果你还有很多疑惑没有解开,可以关注编程网行业资讯频道了解更多相关知识。

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

BeanFactory和FactoryBean的区别有哪些

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

BeanFactory和FactoryBean的区别示例详解

这篇文章主要为大家介绍了BeanFactory和FactoryBean的区别示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
2022-11-13

Spring中BeanFactory FactoryBean和ObjectFactory的三种的区别

关于FactoryBean 和 BeanFactory的对比文章比较多,但是对ObjectFactory的描述就比较少,今天我们对比下这三种的区别,感兴趣的朋友跟随小编一起看看吧
2023-01-17

SpringBeanFactory和FactoryBean有哪些区别

这篇文章主要介绍了SpringBeanFactory与FactoryBean的区别详情,BeanFactory和FactoryBean的区别却是一个很重要的知识点,在本文中将结合源码进行分析讲解,需要的小伙伴可以参考一下
2023-02-14

Spring BeanFactory与FactoryBean的区别是什么

这篇文章主要介绍了Spring BeanFactory与FactoryBean的区别是什么的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Spring BeanFactory与FactoryBean的区别是什么文
2023-06-30

php=== 和==的区别有哪些

这篇文章主要介绍“php === 和==的区别有哪些”,在日常操作中,相信很多人在php === 和==的区别有哪些问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”php === 和==的区别有哪些”的疑惑有所
2023-06-25

c#和java的区别有哪些

Java和C#都是编程的语言,它们是两个不同方向的两种语言。相同点:他们都是面向对象的语言,也就是说,它们都能实现面向对象的思想(封装、继承、多态)。区别:1.c#中的命名空间是namespace类似于Java中的package(包),在Java中导入包用im
c#和java的区别有哪些
2021-05-04

c11和dtp的区别有哪些

小编给大家分享一下c11和dtp的区别有哪些,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!区别:c11屏幕是由日本东芝公司生成的手机屏幕,而dtp屏幕是由韩国LG公司生成的手机屏幕。c11屏幕的可替换性好,而dtp屏幕的可
2023-06-08

php5.4和5.6的区别有哪些

这篇文章主要介绍了php5.4和5.6的区别有哪些的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇php5.4和5.6的区别有哪些文章都会有所收获,下面我们一起来看看吧。PHP5.4和5.6的区别是:1、5.6版
2023-07-02

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录