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 ...
随机推荐
- P3868 [TJOI2009]猜数字
[TJOI2009]猜数字 中国剩余定理 求解i=1 to n : x≡a[i] (mod b[i])的同余方程组 设 t= ∏i=1 to n b[i] 我们先求出 i=1 to n : x≡1 ( ...
- 20145303刘俊谦 《网络对抗》Exp9 Web安全基础实践
20145303刘俊谦 <网络对抗>Exp9 Web安全基础实践 基础问题回答 1.SQL注入原理,如何防御 SQL注入 就是通过把SQL命令插入到"Web表单递交"或 ...
- 使用libcurl开源库和Duilib做的下载文件并显示进度条的小工具
转载:http://blog.csdn.net/mfcing/article/details/43603525 转载:http://blog.csdn.net/infoworld/article/de ...
- Spring Boot条件注解
一.为什么SpringBoot产生于Spring4? Spring4中增加了@Condition annotation, 使用该Annotation之后,在做依赖注入的时候,会检测是否满足某个条件来决 ...
- redis.conf 配置 详解 中文 2.8
# redis version 2.8.19 # 1k => 1000 bytes# 1kb => 1024 bytes# 1m => 1000000 bytes# 1m ...
- 【第二十三章】 springboot + 全局异常处理
一.单个controller范围的异常处理 package com.xxx.secondboot.web; import org.springframework.web.bind.annotation ...
- Gym - 100342J Triatrip (bitset求三元环个数)
https://vjudge.net/problem/Gym-100342J 题意:给出一个邻接矩阵有向图,求图中的三元环的个数. 思路: 利用bitset暴力求解,记得最后需要/3. #includ ...
- Educational Codeforces Round 1 E. Chocolate Bar dp
题目链接:http://codeforces.com/contest/598/problem/E E. Chocolate Bar time limit per test 2 seconds memo ...
- Couldn't find an AF_INET address for
vim ~/.bashrc #输入内容 export ROS_HOSTNAME=你的hostname export ROS_MASTER_URI=http://(目标主机的IP):11311 expo ...
- Mac OS下安装mvn
Step1: 去官网地址下载 http://maven.apache.org/download.cgi Step2: 解压并且移动到指定到目录下 Step3: 配置环境变量并使之生效 .bash_pr ...