FactoryBean
1. 代码示例
- FactoryClass.java
- FactoryBeanDemo实现FactoryBean接口
- 测试方法
2. FactoryBean的作用
- 在实例化和 IOC/DI 做完后,spring会调用 FactoryBean 类型的接口,返回一个你自己创建的bean交给spring管理,不影响FactoryBeanDemo这个bean(FactoryBeanDemo在一级缓存,FactoryClass在factoryBeanObjectCache缓存)
- 如果要获取到 FactoryBean 类本身,就必须加上”&”符号,比如 beanFactory.getBean(“&beanName”);
- BeanFactory.getBean(“beanName”)只能获取到 getObject()方法返回的实例;
- getObject 方法返回的实例会有单独的缓存存储,跟其他实例不是同一个缓存,对应的缓存是:factoryBeanObjectCache
3. 源码分析
protected Object getObjectForBeanInstance(
Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {
// Don't let calling code try to dereference the factory if the bean isn't a factory.
if (BeanFactoryUtils.isFactoryDereference(name)) {
if (beanInstance instanceof NullBean) {
return beanInstance;
}
if (!(beanInstance instanceof FactoryBean)) {
throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass());
}
}
// Now we have the bean instance, which may be a normal bean or a FactoryBean.
// If it's a FactoryBean, we use it to create a bean instance, unless the
// caller actually wants a reference to the factory.
// 1.如果实例不是FactoryBean类型的,或者name是以&号开头的,则直接返回实例(这里就FactoryBeanDemo这个类)
if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
return beanInstance;
}
// 2.如果代码能走下来,则说明 beanName不是以&开头,并且beanInstance是FactoryBean类型的
Object object = null;
if (mbd == null) {
// 3.从factoryBeanObjectCache缓存里面拿FactoryBean类型的实例
object = getCachedObjectForFactoryBean(beanName);
}
if (object == null) {
// Return bean instance from factory.
FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
// Caches object obtained from FactoryBean if it is a singleton.
if (mbd == null && containsBeanDefinition(beanName)) {
mbd = getMergedLocalBeanDefinition(beanName);
}
boolean synthetic = (mbd != null && mbd.isSynthetic());
// 4.重点看,调用了FactoryBean的getObject方法
object = getObjectFromFactoryBean(factory, beanName, !synthetic);
}
return object;
}
- 调用getObject()方法
- 缓存到factoryBeanObjectCache中
- 自己实现的接口