Spring扩展点之FactoryBean接口

旧城等待, 2024-04-19 13:03 195阅读 0赞

首先看一下接口定义








  1. 1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23

  1. public interface FactoryBean<T> {


    /
    返回对象实例
    /
    @Nullable
    T getObject() throws Exception;

    /

    返回对象类型,
    /
    @Nullable
    Class<?> getObjectType();

    /*
    该工厂管理的对象是否为单例?
    */
    default boolean isSingleton() {

    return true;
    }

    }

由接口定义可以看出来,实现这个接口的bean不是主要功能,getObject()创建的对象才是重点。那么在这我们就可以猜到了,可以是使用FactoryBean创建一些实例化过程比较复杂的bean

FactoryBean的注册

FactoryBean的处理逻辑在AbstractBeanFactory.doGetBean方法内








  1. 1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14

  1. 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








  1. 1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93

  1. 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 FactoryBeans 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 FactoryBeans object failed, ex);
    }
    }
    return object;
    }
    }

生成bean对象的方法:








  1. 1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36

  1. 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的实现

Spring中实现这个接口的bean有很多,但是我们最熟悉也是最重要的就是在我之前文章中提到过得ProxyFactoryBean这个bean是实现AOP技术的重点,简单回顾一下

640?wx\_fmt=png








  1. 1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
  1. 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;
    }

往期好文

如果文章对您有所帮助,收藏、转发、在看安排一下!!!

发表评论

表情:
评论列表 (有 0 条评论,195人围观)

还没有评论,来说两句吧...

相关阅读