(以下内容翻译自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的更多相关文章

  1. 聊聊Spring的FactoryBean其实没那么难

    前言 谈到Spring的FactoryBean,就会知道Spring中经典的面试题:FactoryBean和BeanFactory的区别.我们这里就简单概括下: . BeanFactory是接口,提供 ...

  2. Spring之FactoryBean

    首先要分辨BeanFactory 与 FactoryBean的区别, 两个名字很像,所以容易搞混 BeanFactory: 以Factory结尾,表示它是一个工厂类,是用于管理Bean的一个工厂 Fa ...

  3. Spring错误——Spring 注解——factory-bean reference points back to the same bean definition

    背景:学习Spring,在使用注解@Bean的name属性配置<bean>实例时,不能注册实例成功 报错 WARNING: Exception encountered during con ...

  4. Spring的FactoryBean使用

     Spring中有两种类型的Bean,一种是普通Bean,另一种是工厂Bean,即FactoryBean.工厂Bean跟普通Bean不同,其返回的对象不是指定类的一个实例,其返回的是该工厂Bean的g ...

  5. spring 之 factory-bean & factory-method

    这两者常常是一起出现的,或者说他们经常是一起被使用的.但是其实是分为了两种情况: 1 同时使用factory-bean 和 factory-method 如果,我们在一个bean 元素上同时配置 fa ...

  6. Spring中FactoryBean与BeanFactory的区别

    版本:spring-framework-4.1 一概述 BeanFactory 与 FactoryBean的区别, 两个名字很像,面试中也经常遇到,所以容易搞混,现从源码以及示例两方面来分析. 二.源 ...

  7. Spring中FactoryBean的作用和实现原理

    BeanFactory与FactoryBean,相信很多刚翻看Spring源码的同学跟我一样很好奇这俩货怎么长得这么像,分别都是干啥用的.BeanFactory是Spring中Bean工厂的顶层接口, ...

  8. 【带你手撸Spring】没有哪个框架开发,能离开 Spring 的 FactoryBean!

    作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 老司机,你的砖怎么搬的那么快? 是有劲?是技巧?是后门?总之,那个老司机的代码总是可 ...

  9. Spring 通过FactoryBean配置Bean

    1.实现FactoryBean接口 import org.springframework.beans.factory.FactoryBean; public class CarFactoryBean ...

随机推荐

  1. bzoj1654 / P2863 [USACO06JAN]牛的舞会The Cow Prom

    P2863 [USACO06JAN]牛的舞会The Cow Prom 求点数$>1$的强连通分量数,裸的Tanjan模板. #include<iostream> #include&l ...

  2. django 项目中使用多数据库 multiple databases

    假如在一个django项目中使用到了不只一个数据库, 其实这在大一点的工程中很常见,比如主从库 那么会涉及到如下一些东西 1, 定义 在settings中的DATABASE中定义会使用到的数据,比如除 ...

  3. oracle、Mysql数据库客户端DbVisualizer安装

    原文链接:https://jingyan.baidu.com/article/454316ab675302f7a7c03a9e.html

  4. 使用 Vue.js 结合bootstrap 实现的分页控件

    原文链接:http://blog.csdn.net/qiuhaotc/article/details/53031884 源码下载: http://pan.baidu.com/s/1i4XgH6H 密码 ...

  5. 20145127《java程序设计》第十周学习总结

    Java的网络编程 1.计算机网络概述 (1)路由器和交换机组成了核心的计算机网络,计算机只是这个网络上的节点以及控制等,通过光纤.网线等连接将设备连接起来,从而形成了一张巨大的计算机网络. (2)网 ...

  6. 20145227鄢曼君《网络对抗》Web基础

    20145227鄢曼君<网络对抗>Web基础 实验内容 (1)Web前端HTML (2)Web前端javascipt (3)Web后端:MySQL基础:正常安装.启动MySQL,建库.创建 ...

  7. STM32系统时钟为什么没有定义呢

    对于使用3.5版本库开发的STM32学习者 有时候不清楚为什么没有时钟定义 那么我们就简单的讲解下吧: 1,函数从启动文件开始运行(汇编文件) 2,若是hd.s 请看151行LDR     R0, = ...

  8. js实现ajax请求

    练下手,好久没写ajax var xmlhttp=null;//创建XMLHttprequest function createXMLHttpRequest(){ if(window.ActiveXO ...

  9. 安装PYthon+Kivy环境(记录)

    在线翻译 https://www.bing.com/translator/ Cython 0.27 发布了.准确说Cython是单独的一门语言,专门用来写在Python里面import用的扩展库.实际 ...

  10. 如何在一台主机上管理自己的多个git repository

    在使用git时,通常是直接ssh-keygen生成默认秘钥.然后将共钥添加到远程仓库,就可以访问了. 但是,当我们有多个repository时,这种方式就不适用了,因为一个秘钥只能关联一个远程仓库. ...