spring扩展点五:factoryBean的使用
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的使用相关推荐
- beanfactorypostprocessor_Spring源码分析(六)容器的扩展点(BeanFactoryPostProcessor)
之前的文章我写了BeanDefinition的基本概念和合并,其中很对次提到了容器的扩展点,这篇文章就写这方面的知识.这部分的内容主要涉及到官网的1.8小节.按照官网介绍来说,容器的扩展点可以分为三类 ...
- 非常有必要了解的Springboot启动扩展点
点击上方蓝色"方志朋",选择"设为星标" 回复"666"获取独家整理的学习资料! 来源:r6d.cn/r4P7 背景 Spring的核心思想 ...
- 三万字盘点Spring/Boot的那些常用扩展点
Spring对于每个Java后端程序员来说肯定不陌生,日常开发和面试必备的.本文就来盘点Spring/SpringBoot常见的扩展点,同时也来看看常见的开源框架是如何基于这些扩展点跟Spring/S ...
- 盘点Spring/Boot的那些常用扩展点
Spring对于每个Java后端程序员来说肯定不陌生,日常开发和面试必备的.本文就来盘点Spring/SpringBoot常见的扩展点,同时也来看看常见的开源框架是如何基于这些扩展点跟Spring/S ...
- 详解spring生命周期的扩展点
详解spring生命周期的扩展点,加速你追赶高手的脚步 详解spring生命周期的扩展点
- Struts2工作原理和框架扩展点
http://www.cnblogs.com/winstonyan/archive/2011/11/13/struts2_flow_and_extends.html 框架主要涉及技术:Spring + ...
- 实现自定义扩展点_spring扩展API接口介绍
对spring进行定制化功能扩展时,可以选择如下一些扩展点: BeanFactoryPostProcessor 是beanFactory后置处理器,支持在bean factory标准初始化完成后,对b ...
- MVC 的八个扩展点
Asp.net MVC中常用的八个扩展点并举例说明. 一.ActionResult ActionResult代表了每个Action的返回结果.asp.net mvc提供了众多内置的ActionResu ...
- Tuscany SCA V1.0中的扩展机制和启动过程中的扩展点[11月29日更新]
2007年9月24日Tuscany SCA 发布了V1.0版本的实现 .本文讲述的内容使用的就是基于这个版本的,代码下载地址 http://incubator.apache.org/tuscany/s ...
- MyBatis的扩展点(plugins)
2019独角兽企业重金招聘Python工程师标准>>> 1.mybatis扩展点plugins mybatis的扩展是通过拦截器Interceptor来实现的,本质上就是JDK的动态 ...
最新文章
- ubuntu安装和查看已安装
- ct读片软件_伦琴影领影像诊断中心:这六大MRI读片技巧,影像医生必须掌握
- OAuth2,JWT,Open-ID Connect和其他令人困惑的事物
- 发布-订阅消息常用通信方式
- lombok依赖_使用Lombok 前你需要知道这些
- 今年双11,阿里业务100%上云
- 1-10:学习shell之进程
- android学习笔记---49_屏幕适配,根据不同手机屏幕大小适配软件界面
- 【机房收费系统】---修改信息
- 芯片领域再起风波 国内IC行业挑战来临
- 阿里P7架构师浅谈Java 的年薪 40W 是什么水平?
- FastText在商品分类下的应用(第十届服创大赛全国三等奖)
- 计算机桌面任务栏为白色,电脑中锁定在任务栏的图标无法正常显示变成白色如何解决...
- elementUI中折叠面板箭头图标位置调整
- 思科 接入点 本地转发_H3C无线AP本地转发配置教程2016
- 等保安全计算环境之Windows(安全审计+入侵防范)(二级)
- unity 和安卓互相交互
- 数藏拐点已至,未来行业破局靠什么?
- 《自学是门手艺活》读后感
- 【并发编程】WaitGroup 基本用法和如何实现以及常见错误
热门文章
- 容器技术Docker K8s 12 容器服务Kubernetes版ACK详解-使用镜像快速创建无状态应用
- 阿里云云计算 49 云监控的概念
- 阿里云云计算 17 块存储的分类
- 图片不能有透明通道AppStore images can't contain alpha channels or transparencies windows iOS
- 16广义逆的计算及应用
- 2020 金山云 面经
- java对象调用方法,java 对象调用
- rs485如何使用_气体检测仪rs485和4-20ma接线方式有什么区别,该如何选择最优的接线方式...
- python统计中文字数_Python实现统计文本文件字数的方法
- 随机抽样方法正太分布 MC, MCMC, Gibbs采样 原理实现(in R)