Spring源码学习--FactoryBean实现原理
来源:互联网 发布:js 引用后面 带时间戳 编辑:程序博客网 时间:2024/06/05 18:01
1、概述
spring中有两种类型的Bean:一种是普通的JavaBean;另一种就是工厂Bean(FactoryBean),这两种Bean都受Spring的IoC容器管理,但它们之间却有一些区别。
2、详述
普通的JavaBean不再多说,我们将其定义好,然后在配置文件中定义并配置其依赖关系,就可以通过IoC容器的getBean获取到。
那么FactoryBean呢?
FactoryBean跟普通Bean不同,它是实现了FactoryBean<T>接口的Bean,通过BeanFactory类的getBean方法直接获取到的并不是该FactoryBean的实例,而是该FactoryBean中方法getObject返回的对象。但我们可以通过其它途径获取到该FactoryBean的实例,方法就是在通过getBean方法获取实例时在参数name前面加上“&”符号即可。
FactoryBean接口提供的方法如下:
public interface FactoryBean<T> {//获取FactoryBean初始化的Bean实例T getObject() throws Exception;//获取Bean实例的类型Class<?> getObjectType();//判断是否是单例模式boolean isSingleton();}
3、示例
创建MyFactoryBean:
public class MyFactoryBean implements FactoryBean<Date>,BeanNameAware { private String name; @Override public Date getObject() throws Exception { return new Date(); } @Override public Class<?> getObjectType() { return Date.class; } @Override public boolean isSingleton() { return false; } public void sayName() { System.out.println("My name is " + this.name); } @Override public void setBeanName(String name) { this.name = name; } }在Spring的配置文件ApplicationContext.xml中注入MyFactoryBean
<bean id ="myFactoryBean" class="com.xxxx.MyFactoryBean"></bean>测试代码
public class MainFactoryBean {@SuppressWarnings("resource")public static void main(String [] args){ ApplicationContext appCtx = new ClassPathXmlApplicationContext("applicationContext.xml"); Date now = (Date) appCtx.getBean("myFactoryBean"); System.out.println(now); MyFactoryBean factoryBean = (MyFactoryBean) appCtx.getBean("&myFactoryBean"); factoryBean.sayName(); } }运行结果:通过myFactoryBean名称获取到的Bean是Date对象实例,通过&myFactoryBean获取到的是MyFactoryBean对象实例。
4、实现原理
我们来看一下执行Date now = (Date) appCtx.getBean("myFactoryBean"); 时会做的处理操作。
AbstractBeanFactory中会进行一系列的操作。
getBean获取bean
@Overridepublic Object getBean(String name) throws BeansException {return doGetBean(name, null, null, false);}doGetBean中获取bean实例
protected <T> T doGetBean(final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)throws BeansException {.........//省略部分代码bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);.........//省略部分代码return (T) bean;}getObjectForBeanInstance中会选择bean实例是普通的Bean还是FactoryBean,同时通过判断name中是否有&来选择判断是或者FactoryBean还是其getObject方法中获取的bean
protected Object getObjectForBeanInstance(Object beanInstance, String name, String beanName, RootBeanDefinition mbd) {.........//省略部分代码//判断bean类型是否是FactoryBean,或者name是否是以&开头,如果是则直接返回if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {return beanInstance;}//如果是则从getObjectFromFactoryBean中获取if (object == null) {// Return bean instance from factory.FactoryBean<?> factory = (FactoryBean<?>) beanInstance;if (mbd == null && containsBeanDefinition(beanName)) {mbd = getMergedLocalBeanDefinition(beanName);}boolean synthetic = (mbd != null && mbd.isSynthetic());object = getObjectFromFactoryBean(factory, beanName, !synthetic);}return object;}getObjectFromFactoryBean接下来会执行FactoryBean的getObject方法获取bean了。
protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {.........//省略部分代码Object object = doGetObjectFromFactoryBean(factory, beanName);.........//省略部分代码return object;}private Object doGetObjectFromFactoryBean(final FactoryBean<?> factory, final String beanName)throws BeanCreationException {Object object;.........//省略部分代码//调用Factory的getObject方法object = factory.getObject();.........//省略部分代码return object;}总结:Spring对FactoryBean的实现机制是当你获取一个Bean时,如果获取的Bean的类型是FactoryBean,并且其name中并没有&则调用bean的getObject方法获取FactoryBean实现类中提供bean,否则就是直接返回普通的bean类型。
阅读全文
1 0
- Spring源码学习--FactoryBean实现原理
- Spring源码学习之BeanFactory和FactoryBean
- Spring FactoryBean源码浅析
- Spring FactoryBean源码浅析
- Spring FactoryBean源码浅析
- Spring FactoryBean源码浅析
- spring学习4-FactoryBean
- spring学习之FactoryBean
- spring源码分析之FactoryBean
- Spring 源码梳理(五) FactoryBean与BeanFactory
- spring源码学习之路---IOC实现原理(三)
- spring源码学习之路---IOC实现原理
- spring源码学习之路---IOC实现原理(三)
- spring源码学习之路---IOC实现原理(三)
- spring源码学习之路---IOC实现原理(二)
- spring学习之FactoryBean学习(一)
- spring学习之FactoryBean学习(二)
- FactoryBean的实现原理与作用
- 批量删除Redis中hash map的指定pattern的key
- mysql数据库对空格的查询处理
- hadoop +hbase +zookeeper 完全分布搭建 (版本一)
- 缩小窗口时CSS背景图出现右侧空白BUG的解决方法
- Java调用Document.getElementById方法返回null的解决办法
- Spring源码学习--FactoryBean实现原理
- One-Hot Encoding
- AngularJS的学习--$on、$emit和$broadcast的使用
- HashMap源码分析
- java中使用WebView提取指定网页的HTML内容
- 自定义View一仿宝头条1号店京东垂直滚动的公告(广告)条
- Window和Linux多核多线程同步异步IPC机制
- Linux Centos下软件的安装与卸载方法
- Sublime报Decode error