1. 程式人生 > >FactoryBean的實現原理與作用

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;  
    } 
第一個方法就是區分單例還是多例,第二個方法是真真的呼叫getObject的方法獲得FactoryBean生產的物件。從程式碼中可以看到,具體產生Bean的地方時這個getObject方法,Spring為這個FactoryBean提供了70多個實現,比如Poxy、JDNI、RMI等等。所以我們不再舉例,看個截圖,下面我們將自己動手實現一個FactoryBean。


FactoryBean的舉例理解