Spring扩展接口-FactoryBean
.markdown-body { line-height: 1.75; font-weight: 400; font-size: 16px; overflow-x: hidden; color: rgba(37, 41, 51, 1) }
.markdown-body h1, .markdown-body h2, .markdown-body h3, .markdown-body h4, .markdown-body h5, .markdown-body h6 { line-height: 1.5; margin-top: 35px; margin-bottom: 10px; padding-bottom: 5px }
.markdown-body h1 { font-size: 24px; line-height: 38px; margin-bottom: 5px }
.markdown-body h2 { font-size: 22px; line-height: 34px; padding-bottom: 12px; border-bottom: 1px solid rgba(236, 236, 236, 1) }
.markdown-body h3 { font-size: 20px; line-height: 28px }
.markdown-body h4 { font-size: 18px; line-height: 26px }
.markdown-body h5 { font-size: 17px; line-height: 24px }
.markdown-body h6 { font-size: 16px; line-height: 24px }
.markdown-body p { line-height: inherit; margin-top: 22px; margin-bottom: 22px }
.markdown-body img { max-width: 100% }
.markdown-body hr { border-top: 1px solid rgba(221, 221, 221, 1); border-right: none; border-bottom: none; border-left: none; margin-top: 32px; margin-bottom: 32px }
.markdown-body code { border-radius: 2px; overflow-x: auto; background-color: rgba(255, 245, 245, 1); color: rgba(255, 80, 44, 1); font-size: 0.87em; padding: 0.065em 0.4em }
.markdown-body code, .markdown-body pre { font-family: Menlo, Monaco, Consolas, Courier New, monospace }
.markdown-body pre { overflow: auto; position: relative; line-height: 1.75 }
.markdown-body pre>code { font-size: 12px; padding: 15px 12px; margin: 0; word-break: normal; display: block; overflow-x: auto; color: rgba(51, 51, 51, 1); background: rgba(248, 248, 248, 1) }
.markdown-body a { text-decoration: none; color: rgba(2, 105, 200, 1); border-bottom: 1px solid rgba(209, 233, 255, 1) }
.markdown-body a:active, .markdown-body a:hover { color: rgba(39, 91, 140, 1) }
.markdown-body table { display: inline-block !important; font-size: 12px; width: auto; max-width: 100%; overflow: auto; border: 1px solid rgba(246, 246, 246, 1) }
.markdown-body thead { background: rgba(246, 246, 246, 1); color: rgba(0, 0, 0, 1); text-align: left }
.markdown-body tr:nth-child(2n) { background-color: rgba(252, 252, 252, 1) }
.markdown-body td, .markdown-body th { padding: 12px 7px; line-height: 24px }
.markdown-body td { min-width: 120px }
.markdown-body blockquote { color: rgba(102, 102, 102, 1); padding: 1px 23px; margin: 22px 0; border-left: 4px solid rgba(203, 203, 203, 1); background-color: rgba(248, 248, 248, 1) }
.markdown-body blockquote:after { display: block; content: "" }
.markdown-body blockquote>p { margin: 10px 0 }
.markdown-body ol, .markdown-body ul { padding-left: 28px }
.markdown-body ol li, .markdown-body ul li { margin-bottom: 0; list-style: inherit }
.markdown-body ol li .task-list-item, .markdown-body ul li .task-list-item { list-style: none }
.markdown-body ol li .task-list-item ol, .markdown-body ol li .task-list-item ul, .markdown-body ul li .task-list-item ol, .markdown-body ul li .task-list-item ul { margin-top: 0 }
.markdown-body ol ol, .markdown-body ol ul, .markdown-body ul ol, .markdown-body ul ul { margin-top: 3px }
.markdown-body ol li { padding-left: 6px }
.markdown-body .contains-task-list { padding-left: 0 }
.markdown-body .task-list-item { list-style: none }
@media (max-width: 720px) { .markdown-body h1 { font-size: 24px } .markdown-body h2 { font-size: 20px } .markdown-body h3 { font-size: 18px } }.markdown-body pre, .markdown-body pre>code.hljs { color: rgba(51, 51, 51, 1); background: rgba(248, 248, 248, 1) }
.hljs-comment, .hljs-quote { color: rgba(153, 153, 136, 1); font-style: italic }
.hljs-keyword, .hljs-selector-tag, .hljs-subst { color: rgba(51, 51, 51, 1); font-weight: 700 }
.hljs-literal, .hljs-number, .hljs-tag .hljs-attr, .hljs-template-variable, .hljs-variable { color: rgba(0, 128, 128, 1) }
.hljs-doctag, .hljs-string { color: rgba(221, 17, 68, 1) }
.hljs-section, .hljs-selector-id, .hljs-title { color: rgba(153, 0, 0, 1); font-weight: 700 }
.hljs-subst { font-weight: 400 }
.hljs-class .hljs-title, .hljs-type { color: rgba(68, 85, 136, 1); font-weight: 700 }
.hljs-attribute, .hljs-name, .hljs-tag { color: rgba(0, 0, 128, 1); font-weight: 400 }
.hljs-link, .hljs-regexp { color: rgba(0, 153, 38, 1) }
.hljs-bullet, .hljs-symbol { color: rgba(153, 0, 115, 1) }
.hljs-built_in, .hljs-builtin-name { color: rgba(0, 134, 179, 1) }
.hljs-meta { color: rgba(153, 153, 153, 1); font-weight: 700 }
.hljs-deletion { background: rgba(255, 221, 221, 1) }
.hljs-addition { background: rgba(221, 255, 221, 1) }
.hljs-emphasis { font-style: italic }
.hljs-strong { font-weight: 700 }
简介
创建对象最简单的方式是直接使用new操作符,如果创建对象比较繁杂,可以采用工厂模式。同样Spring中提供了FactoryBean接口来帮助创建对象。
public interface FactoryBean<T> {
T getObject() throws Exception;
Class<?> getObjectType();
default boolean isSingleton() {
return true;
}
}
- T getObject():返回由FactoryBean创建的bean实例。bean示例可能是singleton还是prototype取决于isSingleton方法的返回。
- boolean isSingleton():返回由FactoryBean创建的bean实例的作用域是singleton还是prototype。
- Class getObjectType():返回FactoryBean创建的bean类型。
在Spring中,创建bean时,如果该bean实现了FactoryBean接口,那么就会调用getObject方法获取真正的bean, 通过 getBean()方法返回的不是FactoryBean本身,而是FactoryBean#getObject()方法所返回的bean。如果想要获取FactoryBean本身,在beanName前显示的加上 "&" 前缀, 例如getBean("&myBean")。
用途示例
Spring代理实现-ProxyFactoryBean
Spring代理的实现类ProxyFactoryBean,当实例化ProxyFactoryBean时,对原有的singletonInstance对象进行封装,返回的是一个代理对象。Spring常用的AOP,以及事务注解都是基于Spring代理实现。
public class ProxyFactoryBean extends ProxyCreatorSupport implements FactoryBean<Object>, BeanClassLoaderAware, BeanFactoryAware {
@Nullable
private Object singletonInstance; //原有对象
@Nullable
public Object getObject() throws BeansException {
this.initializeAdvisorChain();
if (this.isSingleton()) {
return this.getSingletonInstance();
} else {
if (this.targetName == null) {
this.logger.info("Using non-singleton proxies with singleton targets is often undesirable. Enable prototype proxies by setting the 'targetName' property.");
}
return this.newPrototypeInstance(); //返回代理后的对象
}
}
public Class<?> getObjectType() {
synchronized(this) {
if (this.singletonInstance != null) {
return this.singletonInstance.getClass();
}
}
Class<?>[] ifcs = this.getProxiedInterfaces();
if (ifcs.length == 1) {
return ifcs[0];
} else if (ifcs.length > 1) {
return this.createCompositeInterface(ifcs);
} else {
return this.targetName != null && this.beanFactory != null ? this.beanFactory.getType(this.targetName) : this.getTargetClass();
}
}
public boolean isSingleton() {
return this.singleton;
}
}
自定义bean工厂创建方法
public class CarFactoryBean implements FactoryBean<Car> {
private String carInfo;
public Car getObject() throws Exception {
Car car = new Car();
String[] infos = carInfo.split(",");
car.setBrand(infos[0]);
car.setMaxSpeed(Integer.valueOf(infos[1]));
car.setPrice(Double.valueOf(infos[2]));
return car;
}
public Class<Car> getObjectType() {
return Car.class;
}
public boolean isSingleton() {
return false;
}
}
配置文件添加
<bean id="car" class="com.test.factorybean.CarFactoryBean" carInfo="大众SUV,180,180000"/>
当调用getBean("car") 时,Spring会去调用getObject方法,获取的是Car对象,调用getBean("&car") 时,获取的是该CarFactoryBean示例。
更多信息请移步Spring专栏:www.yuque.com/mrhuang-ire…
```
var code = "89b099c7-7355-41c3-805c-c7f14da1c7eb"
参考:
[1].[https://docs.spring.io/spring-framework/docs/4.3.15.RELEASE/spring-framework-reference/htmlsingle/#beans-factory-extension-factorybean](https://docs.spring.io/spring-framework/docs/4.3.15.RELEASE/spring-framework-reference/htmlsingle/#beans-factory-extension-factorybean)
Spring扩展接口-FactoryBean的更多相关文章
- Spring8:一些常用的Spring Bean扩展接口
前言 Spring是一款非常强大的框架,可以说是几乎所有的企业级Java项目使用了Spring,而Bean又是Spring框架的核心. Spring框架运用了非常多的设计模式,从整体上看,它的设计严格 ...
- 深入理解Spring系列之八:常用的扩展接口
转载 https://mp.weixin.qq.com/s/XfhZltSlTall8wKwV_7fKg Spring不仅提供了一个进行快速开发的基础框架,而且还提供了很多可扩展的接口,用于满足一些额 ...
- Spring拓展接口之FactoryBean,我们来看看其源码实现
前言 开心一刻 那年去相亲,地点在饭店里,威特先上了两杯水,男方绅士的喝了一口,咧嘴咋舌轻放桌面,手抚额头闭眼一脸陶醉,白水硬是喝出了82年拉菲的感觉.如此有生活情调的幽默男人,果断拿下,相处后却发现 ...
- 0001 - Spring 框架和 Tomcat 容器扩展接口揭秘
前言 在 Spring 框架中,每个应用程序上下文(ApplicationContext)管理着一个 BeanFactory,BeanFactory 主要负责 Bean 定义的保存.Bean 的创建. ...
- spring初始化源码浅析之关键类和扩展接口
目录 1.关键接口和类 1.1.关键类之 DefaultListableBeanFactory 1.2.关键类之XmlBeanDefinitionReader 1.3.关键类之ClassPathXml ...
- spring扩展点整理
本文转载自spring扩展点整理 背景 Spring的强大和灵活性不用再强调了.而灵活性就是通过一系列的扩展点来实现的,这些扩展点给应用程序提供了参与Spring容器创建的过程,好多定制化的东西都需要 ...
- spring源码分析系列 (2) spring拓展接口BeanPostProcessor
Spring更多分析--spring源码分析系列 主要分析内容: 一.BeanPostProcessor简述与demo示例 二.BeanPostProcessor源码分析:注册时机和触发点 (源码基于 ...
- Spring BeanFactory与FactoryBean的区别及其各自的详细介绍于用法
Spring BeanFactory与FactoryBean的区别及其各自的详细介绍于用法 1. BeanFactory BeanFactory,以Factory结尾,表示它是一个工厂类(接口),用于 ...
- spring扩展点之三:Spring 的监听事件 ApplicationListener 和 ApplicationEvent 用法,在spring启动后做些事情
<spring扩展点之三:Spring 的监听事件 ApplicationListener 和 ApplicationEvent 用法,在spring启动后做些事情> <服务网关zu ...
- WebService—CXF整合Spring实现接口发布和调用过程
一.CXF整合Spring实现接口发布 发布过程如下: 1.引入jar包(基于maven管理) <!-- cxf --> <dependency> <groupId> ...
随机推荐
- 【docker】如何将服务器加入集群,成为子节点
需求:将服务器加入集群,成为集群中的图一.png (18.95 KB, 下载次数: 0) 图一 图二.png (10.92 KB, 下载次数: 0) 图二 图三.png (26.71 KB, 下载次数 ...
- Two-Stream Convolutional Networks for Action Recognition in Videos论文精读
Two-Stream Convolutional Networks for Action Recognition in Videos论文精读 大家好,今天我要讲的论文是一篇视频理解领域的开山之作,这是 ...
- MySQL-SQL调优-引擎选错索引或者不使用索引分析 和 字符串加索引的方式思考
优化器生成最优执行计划需要考虑的因素 MySQL有一个优化器,专门负责生成最优的查询计划,生成最优查询计划可能考虑的因素有: 扫描行数 是否排序 是否需要回表 是否需要临时表 等等 在不同的因素作用下 ...
- centos7 下全局配置最新版的golang语言开发环境
按照以下步骤进行操作: 前往Go官方网站下载页面(https://golang.org/dl/)查找最新版本的Go二进制文件. 使用wget命令下载最新版本的Go二进制文件.例如,如果最新版本是1.1 ...
- 什么是 Gork ?
Grok 是埃隆·马斯克旗下的人工智能公司 xAI 的开发的一系列大型语言模型 (LLMs)产品,包括Grok 1.Grok 2和即将发布的Grok 3. 受<银河系漫游指南>的启发,Gr ...
- Go初入武林之乘法表
为统一管理源码, 请到gitee中查看. GoTimesTable
- 学习unigui【17】-数据集和JSON互相转换-DataSetConverter4D 开源项目
学习unigui过程中,出现使用json和fdquery等数据交换的太多场景要求. 感谢开源DataSetConverter4D提供轮子. 直接抄demo: {Convert DataSet to J ...
- 关于TFDMemtable的使用场景【2】处理SOAP/REST取得的数据
如果可以直接获得JSON数据,那么可以直接连到TFDMemtable进行显示和编辑. 1.一组REST组件.RESTClient的属性BaseURL是http地址. 2.点击TRESTRequest右 ...
- Clean DDD 技术沙龙 2025 杭州站
整洁领域驱动设计(Clean DDD)第一次线下活动来了,这是: 一个软件设计的全新视角 一次复杂度掌控感的深度体验 一场软件工程效率的探索之旅 活动时间:2025年4月13日星期日 下午 13:00 ...
- Semaphore.acquire()方法的底层原理
一.acquire() 的工作流程 当调用 acquire() 方法时,实际调用的是 AQS 的 acquireSharedInterruptibly(1) 方法.以下是其详细工作流程: // acq ...