7.Spring源碼之路-DefaulListableBeanFactory - FactoryBeanRegistrySupport

Spring源碼之路-DefaulListableBeanFactory

總結

  1. FactoryBeanRegistrySupport 是抽象類繼承了DefaultSingletonBeanRegistry那就擁有了單例Bean註冊的所有功能,此外又擴展了FactoryBean的Bean的支持。
  2. FactoryBean也是一個Bean,主要作用就是通過工廠方法獲取Bean的一種方式,可以讓用戶通過實現FactoryBean接口,來進行創建Bean.
  3. 這裏有一個方法protected Object postProcessObjectFromFactoryBean(Object object, String beanName)是當調用FactoryBean的getObject()方法以後允許對Bean進行一些後置處理。屬於擴展方法。
  4. 這個類中的成員變量private final Map<String, Object> factoryBeanObjectCache = new ConcurrentHashMap<>(16);主要是緩存通過FactoryBean的getObject()方法構造出來的單例Bean。這裏發現緩存通過FactoryBean的getObject()方法構造出來的單例Bean的Map和正常的單例Bean實例存放的map不是同一個。DefaultSingletonBeanRegistrysingletonObjects中存放FactoryBean的單例實例,而factoryBeanObjectCache中存放的是由FactoryBean的getObject()方法所產生的實例,所以並不衝突

源碼註釋的大概翻譯

/**
 * 支持需要處理
 * {@link org.springframework.beans.factory.FactoryBean}實例的單例註冊表的基類,並與
 * {@link DefaultSingletonBeanRegistry}的單例管理集成在一起。 
 *
 * 用作{@link AbstractBeanFactory}的基類。 
 * @author Juergen Hoeller
 * @since 2.5.1
 */
public abstract class FactoryBeanRegistrySupport extends DefaultSingletonBeanRegistry {

	/** 由FactoryBeans創建的單例對象的緩存:對象的FactoryBean名稱。 */
	private final Map<String, Object> factoryBeanObjectCache = new ConcurrentHashMap<>(16);


	/**
	 * 確定給定FactoryBean的類型。 
	 * @param factoryBean 要檢查的FactoryBean實例
	 * @return  返回FactoryBean的對象類型,或者如果尚未確定類型,則返回{@code null} 
	 * or {@code null} if the type cannot be determined yet
	 */
	@Nullable
	protected Class<?> getTypeForFactoryBean(final FactoryBean<?> factoryBean) {
		try {
			if (System.getSecurityManager() != null) {
				return AccessController.doPrivileged((PrivilegedAction<Class<?>>)
						factoryBean::getObjectType, getAccessControlContext());
			}
			else {
				return factoryBean.getObjectType();
			}
		}
		catch (Throwable ex) {
			// Thrown from the FactoryBean's getObjectType implementation.
			logger.info("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;
		}
	}

	/**
	 * 以緩存形式從給定的FactoryBean獲取要公開的對象
	 * 快速檢查最小同步。 
	 * @param beanName bean的名稱
	 * @return 返回從FactoryBean獲得的對象,如果不可用返回 {@code null}
	 */
	@Nullable
	protected Object getCachedObjectForFactoryBean(String beanName) {
		return this.factoryBeanObjectCache.get(beanName);
	}

	/**
	 * 獲取要從給定FactoryBean中公開的對象
	 * @param factory factoryFactory實例的工廠
	 * @param beanName Bean的名稱
	 * @param shouldPostProcess Bean是否要進行後處理
	 * @return 返回從FactoryBean獲得的對象
	 * @throws BeanCreationException 如果FactoryBean對象創建失敗
	 * @see org.springframework.beans.factory.FactoryBean#getObject()
	 */
	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) {
					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)) {
							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;
		}
	}

	/**
	 * 獲取要從給定FactoryBean中公開的對象。
	 * @param factory FactoryBean實例
	 * @param beanName Bean的名稱
	 * @return 返回從FactoryBean獲得的對象
	 * @throws BeanCreationException 如果FactoryBean對象創建失敗
	 * @see org.springframework.beans.factory.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((PrivilegedExceptionAction<Object>) 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) {
			if (isSingletonCurrentlyInCreation(beanName)) {
				throw new BeanCurrentlyInCreationException(
						beanName, "FactoryBean which is currently in creation returned null from getObject");
			}
			object = new NullBean();
		}
		return object;
	}

	/**
	 * 對從FactoryBean獲得的給定對象進行後置處理。 
	 * 結果對象將暴露給bean引用。 
	 * 默認實現只是按原樣返回給定的對象。 
	 * 子類可以覆蓋它,例如,以應用後處理器。
	 * @param object 從FactoryBean獲得的對象。 
	 * @param beanName bean的名稱
	 * @return 返回對象以公開
	 * @throws org.springframework.beans.BeansException 後置處理過程失敗
	 */
	protected Object postProcessObjectFromFactoryBean(Object object, String beanName) throws BeansException {
		return object;
	}

	/**
	 * 如果可能,獲取給定bean的FactoryBean。 
	 * @param beanName Bean的名稱
	 * @param beanInstance 相應的bean實例
	 * @return 將bean實例作爲FactoryBean返回
	 * @throws BeansException 如果給定的bean無法公開爲FactoryBean 
	 */
	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;
	}

	/**
	 * 重寫以清除FactoryBean對象緩存。
	 */
	@Override
	protected void removeSingleton(String beanName) {
		synchronized (getSingletonMutex()) {
			super.removeSingleton(beanName);
			this.factoryBeanObjectCache.remove(beanName);
		}
	}

	/**
	 * 重寫以清除FactoryBean對象緩存。
	 */
	@Override
	protected void clearSingletonCache() {
		synchronized (getSingletonMutex()) {
			super.clearSingletonCache();
			this.factoryBeanObjectCache.clear();
		}
	}

	/**
	 * 返回此bean工廠的安全上下文。如果設置了安全管理器
	 * 則將使用此方法返回的安全上下文的特權
	 * 執行與用戶代碼的交互。 
	 * @see AccessController#getContext()
	 */
	protected AccessControlContext getAccessControlContext() {
		return AccessController.getContext();
	}

}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章