spring的FactoryBean
(以下内容翻译自spring/docs/3.2.18.RELEASE)
为具有工厂属性的对象实现FactoryBean接口。
FactoryBean接口是spring IoC 容器实例化逻辑的一点补充。
如果你有一个复杂的对象,更适合用java代码描述而不是xml,你可以创建自己的FactoryBean,
并在类中写复杂的实例化代码,然后把自定义的FactoryBean加入到spring容器中。
示例:
<bean id="myBean" class="com.dao.MyFactoryBean"></bean>
public class ComplexObj {
public Date date;
public ComplexObj() {
System.out.println("ComplexObj construtcor");
}
}
public class MyFactoryBean implements FactoryBean<ComplexObj> {
public MyFactoryBean() {
System.out.println("MyFactoryBean constructor");
}
@Override
public ComplexObj getObject() throws Exception {
ComplexObj obj = new ComplexObj();
obj.date = new Date();
return obj;
}
@Override
public Class<?> getObjectType() {
return ComplexObj.class;
}
@Override
public boolean isSingleton() {
return false;
}
}
getBean("myBean"); //返回FactoryBean创建的对象
getBean("&myBean"); //返回FactoryBean对象自身
Object bean = appCtx.getBean("myBean");
System.out.println(bean);
Object bean2 = appCtx.getBean("&myBean");
System.out.println(bean2);
1. spring容器创建MyFactoryBean的调用栈,就是一个普通单例bean的创建过程:

2. 创建工厂产品的调用栈:

AbstractBeanFactory
// AbstractBeanFactory
protected <T> T doGetBean(
final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
throws BeansException { final String beanName = transformedBeanName(name);
Object bean; // Eagerly check singleton cache for manually registered singletons.
Object sharedInstance = getSingleton(beanName);
//获取工厂的产品对象,走if分支
// sharedInstance是MyFactoryBean对象
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 = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {
...
} // Check if required type matches the type of the actual bean instance.
if (requiredType != null && bean != null && !requiredType.isAssignableFrom(bean.getClass())) {
try {
return getTypeConverter().convertIfNecessary(bean, requiredType);
}
catch (TypeMismatchException ex) {
if (logger.isDebugEnabled()) {
logger.debug("Failed to convert bean '" + name + "' to required type [" +
ClassUtils.getQualifiedName(requiredType) + "]", ex);
}
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
}
return (T) bean;
}
延伸:dubbo的ReferenceBean实现了FactoryBean接口,所以启动consumer的时候,只会创建一个FactoryBean,
并不会去创建invoker代理,只有在触发getBean("xxx")操作时,才会真正去创建invoker代理。
public class ReferenceBean<T> extends ReferenceConfig<T> implements FactoryBean, ApplicationContextAware, InitializingBean {}
spring的FactoryBean的更多相关文章
- 聊聊Spring的FactoryBean其实没那么难
前言 谈到Spring的FactoryBean,就会知道Spring中经典的面试题:FactoryBean和BeanFactory的区别.我们这里就简单概括下: . BeanFactory是接口,提供 ...
- Spring之FactoryBean
首先要分辨BeanFactory 与 FactoryBean的区别, 两个名字很像,所以容易搞混 BeanFactory: 以Factory结尾,表示它是一个工厂类,是用于管理Bean的一个工厂 Fa ...
- Spring错误——Spring 注解——factory-bean reference points back to the same bean definition
背景:学习Spring,在使用注解@Bean的name属性配置<bean>实例时,不能注册实例成功 报错 WARNING: Exception encountered during con ...
- Spring的FactoryBean使用
Spring中有两种类型的Bean,一种是普通Bean,另一种是工厂Bean,即FactoryBean.工厂Bean跟普通Bean不同,其返回的对象不是指定类的一个实例,其返回的是该工厂Bean的g ...
- spring 之 factory-bean & factory-method
这两者常常是一起出现的,或者说他们经常是一起被使用的.但是其实是分为了两种情况: 1 同时使用factory-bean 和 factory-method 如果,我们在一个bean 元素上同时配置 fa ...
- Spring中FactoryBean与BeanFactory的区别
版本:spring-framework-4.1 一概述 BeanFactory 与 FactoryBean的区别, 两个名字很像,面试中也经常遇到,所以容易搞混,现从源码以及示例两方面来分析. 二.源 ...
- Spring中FactoryBean的作用和实现原理
BeanFactory与FactoryBean,相信很多刚翻看Spring源码的同学跟我一样很好奇这俩货怎么长得这么像,分别都是干啥用的.BeanFactory是Spring中Bean工厂的顶层接口, ...
- 【带你手撸Spring】没有哪个框架开发,能离开 Spring 的 FactoryBean!
作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 老司机,你的砖怎么搬的那么快? 是有劲?是技巧?是后门?总之,那个老司机的代码总是可 ...
- Spring 通过FactoryBean配置Bean
1.实现FactoryBean接口 import org.springframework.beans.factory.FactoryBean; public class CarFactoryBean ...
随机推荐
- FTP-IIS Web
快速搭建一个本地的FTP服务器 如果需要开发FTP文件上传下载功能,那么需要在本机上搭建一个本地FTP服务器,方便调试. 第一步:配置IIS Web服务器 1.1 控制面板中找到“程序”并打开 1 ...
- 【前端】Vue.js实现网格列表布局转换
网格列表布局转换 实现效果: 实现代码及注释: <!DOCTYPE html> <html> <head> <title>布局转换</title& ...
- P2894 [USACO08FEB]酒店Hotel 线段树
题目大意 多次操作 查询并修改区间内长度==len的第一次出现位置 修改区间,变为空 思路 类似于求区间最大子段和(应该是这个吧,反正我没做过) 维护区间rt的 从l开始向右的最长长度 从r开始向左的 ...
- 获取String类型汉字乱码,如何进行编码
本文为博主原创,未经允许不得转载: 在解析properties文件中的汉字时,在java代码中解析得到的是一个乱码字符,形如图下: 导致乱码原因:由于在jdk中,默认为gbk编码方式进行编码盒接收的, ...
- HDU 5834 Magic boy Bi Luo with his excited tree(树形dp)
http://acm.hdu.edu.cn/showproblem.php?pid=5834 题意: 一棵树上每个节点有一个价值$Vi$,每个节点只能获得一次,每走一次一条边要花费$Ci$,问从各个节 ...
- hdu 5381 The sum of gcd 莫队+预处理
The sum of gcd Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) P ...
- WPF基础学习笔记整理 (九) 资源
基础知识: WPF的资源是一种保管一系列有用对象的简单方法,方便于重用. WPF UI元素的Resources属性,都是继承自FrameworkElement列,且其类型为ResourceDictio ...
- [CentOS_7.4]Linux编译安装mono环境
一 安装mono 安装过程: 下载mono安装源,配置,编译,安装,设置环境变量. # wget http://download.mono-project.com/sources/mono/mono- ...
- [设计模式][C++]单例模式
参考:http://blog.csdn.net/hackbuteer1/article/details/7460019 单例模式意图是保证一个类仅有一个实例,并提供一个访问它的全局访问点,该实例被所有 ...
- meta 标签
<meta http-equiv="Refresh" content="5;url=http://www.w3school.com.cn" /> & ...