第三章 spring-bean之FactoryBeanRegistrySupport(4)

前言

从FactoryBeanRegistrySupport类的名字可以看出FactoryBeanRegistrySupport负责FactoryBean的注册与支持。如果想知道FactoryBean相关的资料,请阅读spring-bean中关于FactoryBean的解读。

源码解读

public abstract class FactoryBeanRegistrySupport extends DefaultSingletonBeanRegistry {

	//  缓存singleton性质的FactoryBean从getObject得到的对象
	private final Map<String, Object> factoryBeanObjectCache = new ConcurrentHashMap<String, Object>(16);

	// 从factoryBean.getObjectType()中得到obejctTpye。
	protected Class<?> getTypeForFactoryBean(final FactoryBean<?> factoryBean) {
		try {
			if (System.getSecurityManager() != null) {
				return AccessController.doPrivileged(new PrivilegedAction<Class<?>>() {
					@Override
					public Class<?> run() {
						return factoryBean.getObjectType();
					}
				}, getAccessControlContext());
			}
			else {
				return factoryBean.getObjectType();
			}
		}
		catch (Throwable ex) {
			// Thrown from the FactoryBean's getObjectType implementation.
			logger.warn("FactoryBean threw exception from getObjectType, despite the contract saying " +
					"that it should return null if the type of its object cannot be determined yet", ex);
			return null;
		}
	}

// 通过beanName从缓存中得到对象
	protected Object getCachedObjectForFactoryBean(String beanName) {
		Object object = this.factoryBeanObjectCache.get(beanName);
		return (object != NULL_OBJECT ? object : null);
	}

	//  调用getCachedObjectForFactoryBean之后,识别结果为空,才会调用getObjectFromFactoryBean方法
	//
	protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
		if (factory.isSingleton() && containsSingleton(beanName)) {
			synchronized (getSingletonMutex()) {// 获得DefaultSingletonBeanRegistry中的锁
				Object object = this.factoryBeanObjectCache.get(beanName);// 在并发时候,线程A,B注入A(FactoryBean),A线程注册时,没有,
				if (object == null) {// A线程注册时,没有, 就从FactoryBean 得到 object
					object = doGetObjectFromFactoryBean(factory, beanName);// 从FactoryBean 得到 object
					// 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 (object != null && shouldPostProcess) {
							try {
								object = postProcessObjectFromFactoryBean(object, beanName);// 处理从FactoryBean得到的对象
							}
							catch (Throwable ex) {
								throw new BeanCreationException(beanName,
										"Post-processing of FactoryBean's singleton object failed", ex);
							}
						}
						this.factoryBeanObjectCache.put(beanName, (object != null ? object : NULL_OBJECT));//保存在缓存中
					}
				}
				return (object != NULL_OBJECT ? object : null);
			}
		}
		else {
			Object object = doGetObjectFromFactoryBean(factory, beanName);
			if (object != null && shouldPostProcess) {
				try {
					object = postProcessObjectFromFactoryBean(object, beanName);
				}
				catch (Throwable ex) {
					throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", ex);
				}
			}
			return object;
		}
	}

	// 执行调用FactoryBean.getObject()方法而已
	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(new PrivilegedExceptionAction<Object>() {
						@Override
						public Object run() throws Exception {
								return factory.getObject();
							}
						}, acc);
				}
				catch (PrivilegedActionException pae) {
					throw pae.getException();
				}
			}
			else {
				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 && isSingletonCurrentlyInCreation(beanName)) {
			throw new BeanCurrentlyInCreationException(
					beanName, "FactoryBean which is currently in creation returned null from getObject");
		}
		return object;
	}


	protected Object postProcessObjectFromFactoryBean(Object object, String beanName) throws BeansException {
		return object;
	}


	protected FactoryBean<?> getFactoryBean(String beanName, Object beanInstance) throws BeansException {
		if (!(beanInstance instanceof FactoryBean)) {
			throw new BeanCreationException(beanName,
					"Bean instance of type [" + beanInstance.getClass() + "] is not a FactoryBean");
		}
		return (FactoryBean<?>) beanInstance;
	}
	// 重写了DefaultSingletonBeanRegistry的removeSingleton 方法
	protected void removeSingleton(String beanName) {
		super.removeSingleton(beanName);
		this.factoryBeanObjectCache.remove(beanName);
	}

	protected AccessControlContext getAccessControlContext() {
		return AccessController.getContext();
	}

}

总结

FactoryBeanRegistrySupport总体还是相当简单。但是还是有很多细节

  • FactoryBeanRegistrySupport 缓存的不是FactoryBean对象,而是调用FactoryBeangetObject()之后的返回结果
  • FactoryBean也分singleton与非singleton,主要是看FactoryBean.isSingleton()的返回,如果返回false就是非singleton,返回true就是singleton
  • 调用getCachedObjectForFactoryBean之后,识别结果为空,才会调用getObjectFromFactoryBean方法
  • FactoryBeanRegistrySupport在处理singleton factoryBean的时候,使用的是DefaultSingletonBeanRegistry中的锁
  • FactoryBeanRegistrySupport重写了DefaultSingletonBeanRegistry的removeSingleton方法
  • FactoryBeanRegistrySupport的postProcessObjectFromFactoryBean方法可以被重写,postProcessObjectFromFactoryBean方法作用是处理从FactoryBean.getObject()对象
  • 从FactoryBean得到的对象,不会进入bean的生命周期与监控中

转载于:https://my.oschina.net/u/1261452/blog/1859013

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值