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技术的重点,简单回顾一下吧
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; }
上一篇: 友元类的定义和用法
下一篇: 带大家用Python爬取淘宝两千款套套
推荐阅读