為什么要設(shè)計(jì)adaptive?注解在類上和注解在方法上的區(qū)別?
adaptive設(shè)計(jì)的目的是為了識(shí)別固定已知類和擴(kuò)展未知類。
1.注解在類上:代表人工實(shí)現(xiàn)朦促,實(shí)現(xiàn)一個(gè)裝飾類(設(shè)計(jì)模式中的裝飾模式),它主要作用于固定已知類栓始,
? 目前整個(gè)系統(tǒng)只有2個(gè)务冕,AdaptiveCompiler、AdaptiveExtensionFactory幻赚。
? a.為什么AdaptiveCompiler這個(gè)類是固定已知的禀忆?因?yàn)檎麄€(gè)框架僅支持Javassist和JdkCompiler。
? b.為什么AdaptiveExtensionFactory這個(gè)類是固定已知的落恼?因?yàn)檎麄€(gè)框架僅支持2個(gè)objFactory,一個(gè)是spi,另一個(gè)是spring
2.注解在方法上:代表自動(dòng)生成和編譯一個(gè)動(dòng)態(tài)的Adpative類箩退,它主要是用于SPI,因?yàn)閟pi的類是不固定佳谦、未知的擴(kuò)展類戴涝,所以設(shè)計(jì)了動(dòng)態(tài)$Adaptive類.
例如 Protocol的spi類有 injvm dubbo registry filter listener等等 很多擴(kuò)展未知類,
它設(shè)計(jì)了Protocol$Adaptive的類,通過ExtensionLoader.getExtensionLoader(Protocol.class).getExtension(spi類);來提取對(duì)象
為什么dubbo要自己設(shè)計(jì)一套SPI啥刻?
這是原始JDK spi的代碼
ServiceLoader<Command> serviceLoader=ServiceLoader.load(Command.class);?
? for(Command command:serviceLoader){??
? ? ? command.execute();??
? }??
dubbo在原來的基礎(chǔ)上設(shè)計(jì)了以下功能
1.原始JDK spi不支持緩存奸鸯;dubbo設(shè)計(jì)了緩存對(duì)象:spi的key與value 緩存在 cachedInstances對(duì)象里面,它是一個(gè)ConcurrentMap
2.原始JDK spi不支持默認(rèn)值可帽,dubbo設(shè)計(jì)默認(rèn)值:@SPI("dubbo") 代表默認(rèn)的spi對(duì)象娄涩,例如Protocol的@SPI("dubbo")就是 DubboProtocol,
? 通過 ExtensionLoader.getExtensionLoader(Protocol.class).getDefaultExtension()那默認(rèn)對(duì)象
3.jdk要用for循環(huán)判斷對(duì)象映跟,dubbo設(shè)計(jì)getExtension靈活方便蓄拣,動(dòng)態(tài)獲取spi對(duì)象,
? 例如 ExtensionLoader.getExtensionLoader(Protocol.class).getExtension(spi的key)來提取對(duì)象
4.原始JDK spi不支持 AOP功能申窘,dubbo設(shè)計(jì)增加了AOP功能,在cachedWrapperClasses弯蚜,在原始spi類孔轴,包裝了XxxxFilterWrapper XxxxListenerWrapper
5.原始JDK spi不支持 IOC功能剃法,dubbo設(shè)計(jì)增加了IOC,通過構(gòu)造函數(shù)注入,代碼為:wrapperClass.getConstructor(type).newInstance(instance),
dubbo spi 的目的:獲取一個(gè)指定實(shí)現(xiàn)類的對(duì)象。
途徑:ExtensionLoader.getExtension(String name)
實(shí)現(xiàn)路徑:
getExtensionLoader(Class<T> type) 就是為該接口new 一個(gè)ExtensionLoader路鹰,然后緩存起來贷洲。
getAdaptiveExtension() 獲取一個(gè)擴(kuò)展類,如果@Adaptive注解在類上就是一個(gè)裝飾類晋柱;如果注解在方法上就是一個(gè)動(dòng)態(tài)代理類优构,例如Protocol$Adaptive對(duì)象。
getExtension(String name) 獲取一個(gè)指定對(duì)象雁竞。
-----------------------ExtensionLoader.getExtensionLoader(Class<T> type)
ExtensionLoader.getExtensionLoader(Container.class)
? -->this.type = type;
? -->objectFactory = (type == ExtensionFactory.class ? null : ExtensionLoader.getExtensionLoader(ExtensionFactory.class).getAdaptiveExtension());
? ? ?-->ExtensionLoader.getExtensionLoader(ExtensionFactory.class).getAdaptiveExtension()
? ? ? ?-->this.type = type;
? ? ? ?-->objectFactory =null;
執(zhí)行以上代碼完成了2個(gè)屬性的初始化
1.每個(gè)一個(gè)ExtensionLoader都包含了2個(gè)值 type 和 objectFactory
? Class<?> type钦椭;//構(gòu)造器? 初始化時(shí)要得到的接口名
? ExtensionFactory objectFactory//構(gòu)造器? 初始化時(shí) AdaptiveExtensionFactory[SpiExtensionFactory,SpringExtensionFactory]
2.new 一個(gè)ExtensionLoader 存儲(chǔ)在ConcurrentMap<Class<?>, ExtensionLoader<?>> EXTENSION_LOADERS
關(guān)于這個(gè)objectFactory的一些細(xì)節(jié):
1.objectFactory就是ExtensionFactory,它也是通過ExtensionLoader.getExtensionLoader(ExtensionFactory.class)來實(shí)現(xiàn)的碑诉,但是它的objectFactory=null
2.objectFactory作用彪腔,它就是為dubbo的IOC提供所有對(duì)象。
-----------------------getAdaptiveExtension()
-->getAdaptiveExtension()//為cachedAdaptiveInstance賦值
? -->createAdaptiveExtension()
? ? -->getAdaptiveExtensionClass()
? ? ? -->getExtensionClasses()//為cachedClasses 賦值
? ? ? ? -->loadExtensionClasses()
? ? ? ? ? -->loadFile
? ? ? -->createAdaptiveExtensionClass()//自動(dòng)生成和編譯一個(gè)動(dòng)態(tài)的adpative類进栽,這個(gè)類是一個(gè)代理類
? ? ? ? -->ExtensionLoader.getExtensionLoader(com.alibaba.dubbo.common.compiler.Compiler.class).getAdaptiveExtension()
? ? ? ? -->compiler.compile(code, classLoader)
? ? -->injectExtension()//作用:進(jìn)入IOC的反轉(zhuǎn)控制模式德挣,實(shí)現(xiàn)了動(dòng)態(tài)入注
關(guān)于loadfile的一些細(xì)節(jié)
目的:通過把配置文件META-INF/dubbo/internal/com.alibaba.dubbo.rpc.Protocol的內(nèi)容,存儲(chǔ)在緩存變量里面快毛。
cachedAdaptiveClass//如果這個(gè)class含有adative注解就賦值格嗅,例如ExtensionFactory,而例如Protocol在這個(gè)環(huán)節(jié)是沒有的唠帝。
cachedWrapperClasses//只有當(dāng)該class無adative注解屯掖,并且構(gòu)造函數(shù)包含目標(biāo)接口(type)類型,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?例如protocol里面的spi就只有ProtocolFilterWrapper和ProtocolListenerWrapper能命中
cachedActivates//剩下的類襟衰,包含Activate注解
cachedNames//剩下的類就存儲(chǔ)在這里懂扼。
-----------------------getExtension(String name)
getExtension(String name) //指定對(duì)象緩存在cachedInstances;get出來的對(duì)象wrapper對(duì)象,例如protocol就是ProtocolFilterWrapper和ProtocolListenerWrapper其中一個(gè)阀湿。
? -->createExtension(String name)
? ? -->getExtensionClasses()
? ? -->injectExtension(T instance)//dubbo的IOC反轉(zhuǎn)控制赶熟,就是從spi和spring里面提取對(duì)象賦值。
? ? ? -->objectFactory.getExtension(pt, property)
? ? ? ? -->SpiExtensionFactory.getExtension(type, name)
? ? ? ? ? -->ExtensionLoader.getExtensionLoader(type)
? ? ? ? ? -->loader.getAdaptiveExtension()
? ? ? ? -->SpringExtensionFactory.getExtension(type, name)
? ? ? ? ? -->context.getBean(name)
? ? -->injectExtension((T) wrapperClass.getConstructor(type).newInstance(instance))//AOP的簡單設(shè)計(jì)