spring學習之源碼分析--FactoryBeanRegistrySupport

FactoryBeanRegistrySupport

FactoryBeanRegistrySupport抽象類繼承了DefaultSingletonBeanRegistry類,增長了對FactoryBean的處理。segmentfault

類結構

image.png

字段

// 緩存factoryBean的對應關係
private final Map<String, Object> factoryBeanObjectCache = new ConcurrentHashMap<>(16);

方法解析

getTypeForFactoryBean

調用factoryBean的getObjectType方法返回class類型緩存

protected Class<?> getTypeForFactoryBean(final FactoryBean<?> factoryBean) {
    try {
        if (System.getSecurityManager() != null) {
            return AccessController.doPrivileged((PrivilegedAction<Class<?>>)
                    factoryBean::getObjectType, getAccessControlContext());
        }
        else {
            return factoryBean.getObjectType();//調用factoryBean的getObjectType方法返回class類型。
        }
    }
    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;
    }
}

getCachedObjectForFactoryBean

從緩存中經過制定的beanName獲取FactoryBean安全

protected Object getCachedObjectForFactoryBean(String beanName) {
    return this.factoryBeanObjectCache.get(beanName);
}

getObjectFromFactoryBean

protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
    //若是是單例,且已實例化
    if (factory.isSingleton() && containsSingleton(beanName)) {
        //對singletonObjects加鎖
        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)
                // 預防調用上面那個方法時,有對factoryBeanObjectCache設置,因此從新取
                Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
                if (alreadyThere != null) {
                    object = alreadyThere;
                }
                else {
                    if (shouldPostProcess) {//對該對象進行後置處理
                        // 當前正在建立的bean
                        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;
    }
}

doGetObjectFromFactoryBean

調用factoryBean的getObjectType方法返回對象post

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();//調用factoryBean的getObjectType方法返回對象
        }
    }
    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");
        }
        //沒獲取到對象,返回NullBean
        object = new NullBean();
    }
    return object;
}

postProcessObjectFromFactoryBean

預留鉤子this

protected Object postProcessObjectFromFactoryBean(Object object, String beanName) throws BeansException {
    return object;
}

getFactoryBean

返回FactoryBeanspa

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;
}

removeSingleton

除了移除DefaultSingletonBeanRegistry的對應beanName幾個緩存,還要移除factoryBeanObjectCache的緩存code

protected void removeSingleton(String beanName) {
    synchronized (getSingletonMutex()) {
        super.removeSingleton(beanName);
        this.factoryBeanObjectCache.remove(beanName);
    }
}

clearSingletonCache

除了移除DefaultSingletonBeanRegistry的幾個緩存,還要移除factoryBeanObjectCache的緩存對象

protected void clearSingletonCache() {
    synchronized (getSingletonMutex()) {
        super.clearSingletonCache();
        this.factoryBeanObjectCache.clear();
    }
}

getAccessControlContext

獲取安全做用域blog

protected AccessControlContext getAccessControlContext() {
    return AccessController.getContext();
}
相關文章
相關標籤/搜索