首先看一下接口定義緩存
public interface FactoryBean<T> { /** * 返回對象實例 */ @Nullable T getObject() throws Exception; /** * 返回對象類型, */ @Nullable Class<?> getObjectType(); /** * 該工廠管理的對象是否爲單例? */ default boolean isSingleton() { return true; } }
由接口定義能夠看出來,實現這個接口的bean不是主要功能,getObject()
建立的對象纔是重點。那麼在這咱們就能夠猜到了,能夠是使用FactoryBean
建立一些實例化過程比較複雜的beanpost
FactoryBean
的註冊FactoryBean
的處理邏輯在AbstractBeanFactory.doGetBean
方法內ui
protected <T> T doGetBean( final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly) throws BeansException { //獲取bean名稱 final String beanName = transformedBeanName(name); Object bean; //省略部份內容 //這裏就是FactoryBean的相關處理,下面會展開說 bean = getObjectForBeanInstance(sharedInstance, name, beanName, null); //省略部份內容 return (T) bean; }
看一下具體的邏輯,這裏須要注意Spring關於bean的name有個潛規則,凡是以&開頭的bean名稱都默認爲FactoryBean
this
protected Object getObjectForBeanInstance( Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) { // 若是beanName以工廠引用&開頭 if (BeanFactoryUtils.isFactoryDereference(name)) { if (beanInstance instanceof NullBean) { return beanInstance; } // 若是name以&開頭,而beanInstance不是FactoryBean類型,則拋異常 if (!(beanInstance instanceof FactoryBean)) { throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass()); } } // 若是beanInstance不是FactoryBean類型,則直接返回beanInstance // 或者name以&開頭,也直接返回beanInstance,說明咱們就想獲取FactoryBean實例 if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) { return beanInstance; } Object object = null; if (mbd == null) { object = getCachedObjectForFactoryBean(beanName); } if (object == null) { // 此時beanInstance是FactoryBean類型,而name又不是以&開頭; 這是咱們示例工程的狀況,也是最普通、用的最多的狀況 // 將beanInstance強轉成FactoryBean類型 FactoryBean<?> factory = (FactoryBean<?>) beanInstance; // 從緩存中獲取咱們須要的實例對象 if (mbd == null && containsBeanDefinition(beanName)) { mbd = getMergedLocalBeanDefinition(beanName); } boolean synthetic = (mbd != null && mbd.isSynthetic()); // 調用FactoryBean的getObject方法建立咱們須要的實例對象 object = getObjectFromFactoryBean(factory, beanName, !synthetic); } return object; } 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) { //經過factory.getObject獲取 object = doGetObjectFromFactoryBean(factory, beanName); 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進行存儲 this.factoryBeanObjectCache.put(beanName, object); } } } return object; } } else { //非單例的處理,直接經過factory.getObejct獲取,而後再返回給用戶 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; } }
生成bean對象的方法:prototype
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;}
Spring中實現這個接口的bean有不少,可是咱們最熟悉也是最重要的就是在我以前文章中提到過得ProxyFactoryBean
這個bean是實現AOP技術的重點,簡單回顧一下吧 code
public Object getObject() throws BeansException { initializeAdvisorChain(); if (isSingleton()) { return getSingletonInstance(); } else { if (this.targetName == null) { logger.warn("Using non-singleton proxies with singleton targets is often undesirable. " + "Enable prototype proxies by setting the 'targetName' property."); } return newPrototypeInstance(); } } private synchronized Object getSingletonInstance() { if (this.singletonInstance == null) { this.targetSource = freshTargetSource(); if (this.autodetectInterfaces && getProxiedInterfaces().length == 0 && !isProxyTargetClass()) { // Rely on AOP infrastructure to tell us what interfaces to proxy. Class<?> targetClass = getTargetClass(); if (targetClass == null) { throw new FactoryBeanNotInitializedException("Cannot determine target class for proxy"); } setInterfaces(ClassUtils.getAllInterfacesForClass(targetClass, this.proxyClassLoader)); } // Initialize the shared singleton instance. super.setFrozen(this.freezeProxy); this.singletonInstance = getProxy(createAopProxy()); } return this.singletonInstance; }