beanFactory和factoryBean的区别

在说factoryBean的时候,通常会和beanFactory进行对比,这两个名字是比较相似的,但是两者没有任何的关联
beanFactory是操作bean容器的一个接口,提供了getBean()、isSingleton()等方法,我们常说的DefaultListableBeanFactory就是该接口的实现类
factoryBean是spring提供的一个扩展机制,我理解的是:如果我们自己实现了factoryBean接口,那可以自己去初始化一个bean,由spring来完成对bean的实例化,但是初始化的过程,由我们自己控制

spring源码对factoryBean的处理

我们以mybatis和spring整合的时候,所用到的mapperFactoryBean为例,来说明factoryBean是如何使用的

我们前面博客中,有说过,mybatis在和spring整合的时候,在将mapper接口扫描出来,转换为beanDefinition的时候,会把其beanClass设置为mapperFactoryBean,并将自动注入模型设置为2,其中,beanClass设置为mapperFactoryBean就和这里要说的factoryBean有关系,我们来看下设置的代码

org.mybatis.spring.mapper.ClassPathMapperScanner#processBeanDefinitionsdefinition.setBeanClass(this.mapperFactoryBean.getClass());

这里既然设置了beanClass为mapperFactoryBean,那总要有地方要用到,在哪里用的呢?

在调用dogetBean()方法尝试从单实例池中获取bean的时候,会对factoryBean进行处理

org.springframework.beans.factory.support.AbstractBeanFactory#doGetBeanprotected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {/*** 通过name获取beanName,这里不使用name直接作为beanName有两个原因:*  1.name可能是以&开头的,表明调用者想获取FactoryBean本身,而非FactoryBean;在beanFactory中factoryBean的存储也是map格式*    <beanName,bean> 只是说,普通的beanName是没有&这个字符串的,所以,需要将name的首字母移除,这样才能从缓存中拿到factoryBean*  2.还是别名的问题,需要转换*/final String beanName = transformedBeanName(name);Object bean;/*** 1.从单例池中获取当前bean* 2.这里是循环依赖的重要方法之一* 如果取到的sharedInstance不为null,就表示从单实例池中或者二级缓存中,获取到了bean,就无须进行实例化*/// Eagerly check singleton cache for manually registered singletons.Object sharedInstance = getSingleton(beanName);if (sharedInstance != null && args == null) {if (logger.isDebugEnabled()) {if (isSingletonCurrentlyInCreation(beanName)) {logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +"' that is not fully initialized yet - a consequence of a circular reference");}else {logger.debug("Returning cached instance of singleton bean '" + beanName + "'");}}/*** 如果获取到的bean是factoryBean类型的(比如:mybatis的mapper接口就是MapperFactoryBean类型的),就会在下面这行代码中,调用* factoryBean的getObject()方法,完成代理对象的生成或者一些业务逻辑的处理*/bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);}
}

这里可以看到,在从单实例池中获取到bean之后,会调用getObjectForBeanInstance()方法,这个方法中,就是对factorybean的处理
坦白而言,这里处理的逻辑没有完全看懂,所以,就不再往内层深入的说了,后面对这里研究透了,再补充,我们现在可以简单的认为,在这个方法中,会调用factoryBean的getObject()方法,由于mapper接口初始化的beanDefinition设置的factoryBean是MapperFactoryBean,所以,这里会调用mapperFactoryBean.getObject()方法

思考

我们就知道了,spring提供了factoryBean接口,和对factoryBean的处理,至于我们在实现类中是如何写我们自己的业务逻辑的,spring不关心,spring只需要我们保证,在调用factoryBean的getObject()方法的时候,会返回一个对象就可以了,这个对象就是spring需要继续去实例化、属性赋值的对象

个人觉得,factoryBean的主要作用是在第三方框架在和spring整合的时候,可以利用这个扩展点,将第三方框架的class交给spring去管理,因为我们想下,如果mybatis在和spring整合的时候,怎么把一个个接口放到spring容器里面?总不能说在mybatis的源码中,直接依赖于spring的jar包,然后通过@Component注解将mapper注入到spring容器中吧,这样的话,就和spring强耦合了,所以,mybatis就利用了factoryBean这个扩展点,mybatis自己去声明了一个factoryBean的实现类,然后在实现类的getObject()方法中,会返回一个mapper接口所对应的代理对象,然后spring会把这个代理对象,注入到service层,这样的话,我们在调用mapper接口中的方法的时候,实际上调用的是代理对象的invoke方法,然后invoke方法拦截到方法之后,会调用sqlSession的delete、update、select等方法

上面这些,就是自己对factoryBean的一些见解,有其他的想法,后面再随时补充,这个知识点其实也挺简单的,只是觉得单独写一篇笔记记录下来,方便后面随时去记录扩展,就这样

spring扩展点五:factoryBean的使用相关推荐

  1. beanfactorypostprocessor_Spring源码分析(六)容器的扩展点(BeanFactoryPostProcessor)

    之前的文章我写了BeanDefinition的基本概念和合并,其中很对次提到了容器的扩展点,这篇文章就写这方面的知识.这部分的内容主要涉及到官网的1.8小节.按照官网介绍来说,容器的扩展点可以分为三类 ...

  2. 非常有必要了解的Springboot启动扩展点

    点击上方蓝色"方志朋",选择"设为星标" 回复"666"获取独家整理的学习资料! 来源:r6d.cn/r4P7 背景 Spring的核心思想 ...

  3. 三万字盘点Spring/Boot的那些常用扩展点

    Spring对于每个Java后端程序员来说肯定不陌生,日常开发和面试必备的.本文就来盘点Spring/SpringBoot常见的扩展点,同时也来看看常见的开源框架是如何基于这些扩展点跟Spring/S ...

  4. 盘点Spring/Boot的那些常用扩展点

    Spring对于每个Java后端程序员来说肯定不陌生,日常开发和面试必备的.本文就来盘点Spring/SpringBoot常见的扩展点,同时也来看看常见的开源框架是如何基于这些扩展点跟Spring/S ...

  5. 详解spring生命周期的扩展点

    详解spring生命周期的扩展点,加速你追赶高手的脚步 详解spring生命周期的扩展点

  6. Struts2工作原理和框架扩展点

    http://www.cnblogs.com/winstonyan/archive/2011/11/13/struts2_flow_and_extends.html 框架主要涉及技术:Spring + ...

  7. 实现自定义扩展点_spring扩展API接口介绍

    对spring进行定制化功能扩展时,可以选择如下一些扩展点: BeanFactoryPostProcessor 是beanFactory后置处理器,支持在bean factory标准初始化完成后,对b ...

  8. MVC 的八个扩展点

    Asp.net MVC中常用的八个扩展点并举例说明. 一.ActionResult ActionResult代表了每个Action的返回结果.asp.net mvc提供了众多内置的ActionResu ...

  9. Tuscany SCA V1.0中的扩展机制和启动过程中的扩展点[11月29日更新]

    2007年9月24日Tuscany SCA 发布了V1.0版本的实现 .本文讲述的内容使用的就是基于这个版本的,代码下载地址 http://incubator.apache.org/tuscany/s ...

  10. MyBatis的扩展点(plugins)

    2019独角兽企业重金招聘Python工程师标准>>> 1.mybatis扩展点plugins mybatis的扩展是通过拦截器Interceptor来实现的,本质上就是JDK的动态 ...

最新文章

  1. ubuntu安装和查看已安装
  2. ct读片软件_伦琴影领影像诊断中心:这六大MRI读片技巧,影像医生必须掌握
  3. OAuth2,JWT,Open-ID Connect和其他令人困惑的事物
  4. 发布-订阅消息常用通信方式
  5. lombok依赖_使用Lombok 前你需要知道这些
  6. 今年双11,阿里业务100%上云
  7. 1-10:学习shell之进程
  8. android学习笔记---49_屏幕适配,根据不同手机屏幕大小适配软件界面
  9. 【机房收费系统】---修改信息
  10. 芯片领域再起风波 国内IC行业挑战来临
  11. 阿里P7架构师浅谈Java 的年薪 40W 是什么水平?
  12. FastText在商品分类下的应用(第十届服创大赛全国三等奖)
  13. 计算机桌面任务栏为白色,电脑中锁定在任务栏的图标无法正常显示变成白色如何解决...
  14. elementUI中折叠面板箭头图标位置调整
  15. 思科 接入点 本地转发_H3C无线AP本地转发配置教程2016
  16. 等保安全计算环境之Windows(安全审计+入侵防范)(二级)
  17. unity 和安卓互相交互
  18. 数藏拐点已至,未来行业破局靠什么?
  19. 《自学是门手艺活》读后感
  20. 【并发编程】WaitGroup 基本用法和如何实现以及常见错误

热门文章

  1. 容器技术Docker K8s 12 容器服务Kubernetes版ACK详解-使用镜像快速创建无状态应用
  2. 阿里云云计算 49 云监控的概念
  3. 阿里云云计算 17 块存储的分类
  4. 图片不能有透明通道AppStore images can't contain alpha channels or transparencies windows iOS
  5. 16广义逆的计算及应用
  6. 2020 金山云 面经
  7. java对象调用方法,java 对象调用
  8. rs485如何使用_气体检测仪rs485和4-20ma接线方式有什么区别,该如何选择最优的接线方式...
  9. python统计中文字数_Python实现统计文本文件字数的方法
  10. 随机抽样方法正太分布 MC, MCMC, Gibbs采样 原理实现(in R)