千家信息网

BeanFactory和FactoryBean的区别有哪些

发表于:2025-02-22 作者:千家信息网编辑
千家信息网最后更新 2025年02月22日,BeanFactory和FactoryBean的区别有哪些,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。区别说实话,他俩除了名字比较
千家信息网最后更新 2025年02月22日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;  } }
                                       
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

调用FactoryBean#getObject的链路如下图

通过分析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 extends ReferenceConfig implements FactoryBean, ApplicationContextAware, InitializingBean, DisposableBean {      @Override     public Object getObject() {         return get();     }      @Override     @SuppressWarnings({"unchecked"})     public void afterPropertiesSet() throws Exception {          // 省略部分代码          if (shouldInit()) {             getObject();         }     }      }

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

方法 对象 服务 容器 基础 接口 分析 功能 实例 工厂 方式 链路 问题 帮助 主动 事件 时候 更多 源码 缓存 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 cms集中管理服务器参数 2022中国网络安全会议精神 四川安卓软件开发报价 软件开发进展缓慢原因 怎么写网络安全主题教育 服务器制冷设备龙头有几家 邯郸应用软件开发哪家实惠 软件网络安全文档 无线网络安全的特征有哪些 数据库主备和单机有什么区别 云数据库对比 数据库删除的记录能恢复吗 支付宝(中国)网络技术公司 数据库概念范围最大的 平度游戏软件开发公司 软件开发如何去学习 肇庆市网络安全教育平台 数据库中的二义性是什么 数据库变更管理 数据直接从数据库读取数据 哈利波特魔法觉醒怎么修改服务器 网络安全七字口诀 jsp 自动附加数据库 网络摄像头连不上服务器怎么回事 网络安全小视频防诈骗 简述个人网络安全及隐患 七台河政务软件开发费用 朝阳区卜怡网络技术服务 贵州数据网络安全工程经验丰富 北京鸿融网络技术有限公司
0