乐趣区

spring学习之源码分析FactoryBeanRegistrySupport

FactoryBeanRegistrySupport

FactoryBeanRegistrySupport 抽象类继承了 DefaultSingletonBeanRegistry 类,增加了对 FactoryBean 的处理。

类结构

常量

// 缓存 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 方法返回对象

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

预留钩子

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

getFactoryBean

返回 FactoryBean

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 的缓存

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

获取安全作用域

protected AccessControlContext getAccessControlContext() {return AccessController.getContext();
}
退出移动版