欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Spring扩展点之FactoryBean接口

程序员文章站 2022-06-22 10:40:23
前言 首先看一下接口定义 由接口定义可以看出来,实现这个接口的bean不是主要功能, 创建的对象才是重点。那么在这我们就可以猜到了,可以是使用 创建一些实例化过程比较复杂的bean 的注册 的处理逻辑在 方法内 看一下具体的逻辑,这里需要注意Spring关于bean的name有个潜规则,凡是以&开头 ......

前言

首先看一下接口定义

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方法内

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

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对象的方法:

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技术的重点,简单回顾一下吧
Spring扩展点之FactoryBean接口

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