第三章 spring-bean之FactoryBeanRegistrySupport(4)
阿新 • • 發佈:2018-11-28
前言
從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的生命週期與監控中