当前位置: 移动技术网 > IT编程>开发语言>Java > Spring扩展点之FactoryBean接口

Spring扩展点之FactoryBean接口

2019年09月16日  | 移动技术网IT编程  | 我要评论

前言

首先看一下接口定义

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技术的重点,简单回顾一下吧
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;
    }

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网