微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Spring 源码解析之FactoryBean

一个例子

factorybeanDemo类

@Service
public class factorybeanDemo implements factorybean {
    @Override
    public Object getobject() throws Exception {
        return new FactoryB();
    }

    @Override
    public Class<?> getobjectType() {
        return FactoryB.class;
    }
}

FactoryB类`

public class FactoryB {
}

测试代码

 public void test4() {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext("cn.com.dq");
        FactoryB factoryB = (FactoryB) applicationContext.getBean("factorybeanDemo");
        System.out.println(factoryB);
        factorybeanDemo factorybeanDemo = (factorybeanDemo) applicationContext.getBean("&factorybeanDemo");
        System.out.println(factorybeanDemo);
    }

输出结果


从上面的代码可以启发2点思考
1.我们通过beanName=[factorybeanDemo]拿到的bean不是factorybeanDemo的实例,而是FactoryB 的实例
2.我们要想拿到factorybeanDemo的实例而是通过&factorybeanDemo拿到
下面我们从源码上分析上述情况

源码分析

在bean的实例化中,当bean实例化完成以后都会看到这样一行代码,如下:

Abstractbeanfactory

doGetBean()方法

protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
                              @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
		 ...
        if (mbd.isSingleton()) {
            sharedInstance = getSingleton(beanName, () -> {
                try {
                    return createBean(beanName, mbd, args);
                } catch (BeansException ex) {
                    // Explicitly remove instance from singleton cache: It might have been put there
                    // eagerly by the creation process, to allow for circular reference resolution.
                    // Also remove any beans that received a temporary reference to the bean.
                    destroySingleton(beanName);
                    throw ex;
                }
            });
            //该方法factorybean接口的调用入口
            bean = getobjectForBeanInstance(sharedInstance, name, beanName, mbd);
        }
		 ...
    }`
	

factorybean接口的调用入口getobjectForBeanInstance();

getobjectForBeanInstance()

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.
        //如果实例不是factorybean类型的,或者name是以&号开头的,则直接返回实例
        if (!(beanInstance instanceof factorybean) || beanfactoryUtils.isFactoryDereference(name)) {
            return beanInstance;
        }

        //如果代码能走下来,则说明 beanName不是以&开头,并且beanInstance是factorybean类型的
        Object object = null;
        if (mbd == null) {
            //从缓存里面拿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());
            //关键方法
            object = getobjectFromfactorybean(factory, beanName, !synthetic);
        }
        return object;
    }

如下代码

if (!(beanInstance instanceof factorybean) || beanfactoryUtils.isFactoryDereference(name)) {
	return beanInstance;
}

beanfactoryUtils的isFactoryDereference方法如下

public static boolean isFactoryDereference(@Nullable String name) {
	return (name != null && name.startsWith(beanfactory.FACTORY_BEAN_PREFIX));
}

1.上述代码可以解释要拿到factorybeanDemo的实例则是通过&factorybeanDemo拿到
2.如果beanName不是以&开头,并且beanInstance是factorybean类型,会优先在factorybeanObjectCache缓存中拿。
3.第一次肯定是拿不到的,则会执行getobjectFromfactorybean()方法

factorybeanRegistrySupport类

getobjectFromfactorybean()方法

protected Object getobjectFromfactorybean(factorybean<?> factory, String beanName, boolean shouldPostProcess) {
        if (factory.isSingleton() && containsSingleton(beanName)) {
            synchronized (getSingletonMutex()) {
                Object object = this.factorybeanObjectCache.get(beanName);
                if (object == null) {
                    //调用getobject方法
                    object = doGetobjectFromfactorybean(factory, beanName);
                    // Only post-process and store if not put there already during getobject() call above
                    // (e.g. because of circular reference processing triggered by custom getBean calls)
                    Object alreadyThere = this.factorybeanObjectCache.get(beanName);
                    if (alreadyThere != null) {
                        object = alreadyThere;
                    } else {
                        if (shouldPostProcess) {
                            if (isSingletonCurrentlyInCreation(beanName)) {
                                // Temporarily return non-post-processed object, not storing it yet..
                                return object;
                            }
                            beforeSingletonCreation(beanName);
                            try {
                                object = postProcessObjectFromfactorybean(object, beanName);
                            } catch (Throwable ex) {
                                throw new BeanCreationException(beanName,
                                        "Post-processing of factorybean's singleton object Failed", ex);
                            } finally {
                                afterSingletonCreation(beanName);
                            }
                        }
                        if (containsSingleton(beanName)) {
                            //把实例缓存到factorybeanObjectCache map中,这个是单独缓存factorybean类型实例的map
                            this.factorybeanObjectCache.put(beanName, object);
                        }
                    }
                }
                return object;
            }
        } else {
            Object object = doGetobjectFromfactorybean(factory, beanName);
            if (shouldPostProcess) {
                try {
                    object = postProcessObjectFromfactorybean(object, beanName);
                } catch (Throwable ex) {
                    throw new BeanCreationException(beanName, "Post-processing of factorybean's object Failed", ex);
                }
            }
            return object;
        }
    }

方法执行2个比较重要的操作
1.doGetobjectFromfactorybean()
2.将执行doGetobjectFromfactorybean()方法返回的bean的实例放入factorybeanObjectCache缓存中

doGetobjectFromfactorybean()方法

private Object doGetobjectFromfactorybean(final factorybean<?> factory, final String beanName)
			throws BeanCreationException {

		Object object;
		try {
			if (System.getSecurityManager() != null) {
				AccessControlContext acc = getAccessControlContext();
				try {
					object = AccessController.doPrivileged((PrivilegedExceptionAction<Object>) factory::getobject, acc);
				} catch (PrivilegedActionException pae) {
					throw pae.getException();
				}
			} else {
				//调用getobject方法
				object = factory.getobject();
			}
		} catch (factorybeannotinitializedException ex) {
			throw new BeanCurrentlyInCreationException(beanName, ex.toString());
		} catch (Throwable ex) {
			throw new BeanCreationException(beanName, "factorybean threw exception on object creation", ex);
		}

		// Do not accept a null value for a factorybean that's not fully
		// initialized yet: Many factorybeans just return null then.
		if (object == null) {
			if (isSingletonCurrentlyInCreation(beanName)) {
				throw new BeanCurrentlyInCreationException(
						beanName, "factorybean which is currently in creation returned null from getobject");
			}
			object = new NullBean();
		}
		return object;
	}

上述代码可以看到最终调用到了factorybean的getobject()方法
回到示例代码factorybean的getobject()的方法返回的是FactoryB的实例
通过上述的源码分析就能解释我们通过beanName=[factorybeanDemo]拿到的bean不是factorybeanDemo的实例,而是FactoryB 的实例

总结

1.factorybean接口的调用入口是在bean的实例化完成以后
2.bean在实现factorybean接口后通过beanName拿到的不是bean本身的实例而是factorybean接口中getobject()方法返回的实例
3.bean在实现factorybean接口后要拿到bean本身的实例,则是通过&+beanName拿到

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐