FactoryBean的實現原理與作用
阿新 • • 發佈:2019-01-06
第一個方法就是區分單例還是多例,第二個方法是真真的呼叫getObject的方法獲得FactoryBean生產的物件。從程式碼中可以看到,具體產生Bean的地方時這個getObject方法,Spring為這個FactoryBean提供了70多個實現,比如Poxy、JDNI、RMI等等。所以我們不再舉例,看個截圖,下面我們將自己動手實現一個FactoryBean。// Bean工廠生產Bean例項物件 protected Object getObjectFromFactoryBean(FactoryBean factory, String beanName, boolean shouldPostProcess) { // Bean工廠是單態模式,並且Bean工廠快取中存在指定名稱的Bean例項物件 if (factory.isSingleton() && containsSingleton(beanName)) { synchronized (getSingletonMutex()) { // 直接從Bean工廠快取中獲取指定名稱的Bean例項物件 Object object = this.factoryBeanObjectCache.get(beanName); // Bean工廠快取中沒有指定名稱的例項物件,則生產該例項物件 if (object == null) { // 呼叫Bean工廠的getObject方法生產指定Bean的例項物件 object = doGetObjectFromFactoryBean(factory, beanName, shouldPostProcess); // 將生產的例項物件新增到Bean工廠快取中 this.factoryBeanObjectCache.put(beanName, (object != null ? object : NULL_OBJECT)); } return (object != NULL_OBJECT ? object : null); } } // 呼叫Bean工廠的getObject方法生產指定Bean的例項物件 else { return doGetObjectFromFactoryBean(factory, beanName, shouldPostProcess); } } //呼叫Bean工廠的getObject方法生產指定Bean的例項物件 private Object doGetObjectFromFactoryBean( final FactoryBean factory, final String beanName, final boolean shouldPostProcess) throws BeanCreationException { Object object; try { if (System.getSecurityManager() != null) { AccessControlContext acc = getAccessControlContext(); try { //實現PrivilegedExceptionAction介面的匿名內建類 //根據JVM檢查許可權,然後決定BeanFactory建立例項物件 object = AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() { public Object run() throws Exception { //呼叫BeanFactory介面實現類的建立物件方法 return factory.getObject(); } }, acc); } catch (PrivilegedActionException pae) { throw pae.getException(); } } else { //呼叫BeanFactory介面實現類的建立物件方法 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); } //創建出來的例項物件為null,或者因為單態物件正在建立而返回null if (object == null && isSingletonCurrentlyInCreation(beanName)) { throw new BeanCurrentlyInCreationException( beanName, "FactoryBean which is currently in creation returned null from getObject"); } //為創建出來的Bean例項物件新增BeanPostProcessor後置處理器 if (object != null && shouldPostProcess) { try { object = postProcessObjectFromFactoryBean(object, beanName); } catch (Throwable ex) { throw new BeanCreationException(beanName, "Post-processing of the FactoryBean's object failed", ex); } } return object; }