概述
前置項(xiàng)目中桨螺,經(jīng)常有定制的需求科汗,如何更優(yōu)雅實(shí)現(xiàn)定制的需求
前置云端拆分第一階段般卑,是把前置云端的代碼拆分武鲁,第二階段的目標(biāo)是實(shí)現(xiàn)前置云端共用一個(gè)SDK,如何實(shí)現(xiàn)擴(kuò)展性成了一個(gè)問題蝠检,我試著給出自己的思考
設(shè)計(jì)模式
對(duì)于一些有可能發(fā)生變化的地方洞坑,進(jìn)行封裝(關(guān)注點(diǎn)分離),應(yīng)用策略模式蝇率、責(zé)任鏈模式等手段進(jìn)行擴(kuò)展點(diǎn)設(shè)計(jì)迟杂。
擴(kuò)展點(diǎn)
Java原生SPI
JAVA SPI = 基于接口的編程+策略模式+配置文件 的動(dòng)態(tài)加載機(jī)制
對(duì)于Java中的SPI,有如下的約定:
- 在META-INF/services/目錄中創(chuàng)建以接口全限定名命名的文件該文件內(nèi)容為Api具體實(shí)現(xiàn)類的全限定名
- 使用ServiceLoader類動(dòng)態(tài)加載META-INF中的實(shí)現(xiàn)類
- 如SPI的實(shí)現(xiàn)類為Jar則需要放在主程序classPath中
- Api具體實(shí)現(xiàn)類必須有一個(gè)不帶參數(shù)的構(gòu)造方法
實(shí)際上就是JDK的就是ServiceLoader 會(huì)遍歷所有jar查找META-INF/services/接口類名 文件本慕,找到后就加載文件中配置的文件進(jìn)行實(shí)例化使用排拷。
Spring的擴(kuò)展點(diǎn)
SPI實(shí)現(xiàn)機(jī)制
在Spring中提供了SPI機(jī)制,我們只需要在 META-INF/spring.factories 中配置接口實(shí)現(xiàn)類名锅尘,即可通過服務(wù)發(fā)現(xiàn)機(jī)制监氢,在運(yùn)行時(shí)加載接口的實(shí)現(xiàn)類:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration
配置好 spring.factories 文件后,我們就可以通過 SpringFactoriesLoader 動(dòng)態(tài)加載接口實(shí)現(xiàn)類了
BeanFactoryPostProcessor接口
BeanFactory生成后藤违,如果想對(duì)BeanFactory進(jìn)行一些處理浪腐,該怎么辦呢?BeanFactoryPostProcessor接口就是用來處理BeanFactory的顿乒。
BeanDefinitionRegistryPostProcessor接口
在Spring容器初始化時(shí)议街,首先會(huì)讀取應(yīng)用程序中的配置文件,并解析出所有的Bean定義璧榄,然后將這些Bean定義注冊(cè)到容器中特漩。在這個(gè)過程中,BeanDefinitionRegistryProcessor提供了一種機(jī)制骨杂,允許開發(fā)人員在Bean定義注冊(cè)之前和之后對(duì)Bean定義進(jìn)行自定義處理涂身,例如添加,修改或刪除Bean定義等搓蚪。
Mybatis中org.mybatis.spring.mapper.MapperScannerConfigurer就實(shí)現(xiàn)了該方法蛤售,在只有接口沒有實(shí)現(xiàn)類的情況下找到接口方法與sql之間的聯(lián)系從而生成BeanDefinition并注冊(cè)。
BeanPostProcessor接口
在Spring容器實(shí)例化bean之后妒潭,在執(zhí)行bean的初始化方法前后悴能,允許我們自定義修改新的bean實(shí)例,如修改bean的屬性杜耙,可以給bean生成一個(gè)動(dòng)態(tài)代理實(shí)例等等搜骡。
Spring AOP的底層處理也是通過實(shí)現(xiàn)BeanPostProcessor來執(zhí)行代理包裝邏輯的。
AOP
AOP為Aspect Oriented Programming的縮寫佑女,意為:面向切面編程记靡,通過預(yù)編譯方式和運(yùn)行動(dòng)態(tài)代理實(shí)現(xiàn)程序功能的統(tǒng)一維護(hù)的一種技術(shù)谈竿。AOP是OOP的延續(xù),是軟件開發(fā)中的一個(gè)熱點(diǎn)摸吠,也是Spring框架中的一個(gè)重要內(nèi)容空凸,是函數(shù)式編程的一種衍生范型。利用AOP可以對(duì)業(yè)務(wù)邏輯的各個(gè)部分進(jìn)行隔離寸痢,從而使得業(yè)務(wù)邏輯各部分之間的耦合度降低呀洲,提高程序的可重用性,同時(shí)提高開發(fā)的效率啼止。
我們一般做活動(dòng)的時(shí)候道逗,一般對(duì)每一個(gè)接口都會(huì)做活動(dòng)的有效性校驗(yàn)(是否開始、是否結(jié)束等等)献烦、以及這個(gè)接口是不是需要用戶登錄滓窍。
AOP+設(shè)計(jì)模式
可配置化
插件化
常見的動(dòng)態(tài)插件的實(shí)現(xiàn)方式有 SPI、OSGI 等方案巩那,插件化開發(fā)模式正在很多編程語言或技術(shù)框架中得以廣泛的應(yīng)用實(shí)踐吏夯,比如大家熟悉的jenkins,docker可視化管理平臺(tái)rancher即横,以及日常編碼使用的編輯器idea噪生,eclipse等,隨處可見的帶有熱插拔功能的插件东囚,讓系統(tǒng)像插了翅膀一樣跺嗽,大大提升了系統(tǒng)的擴(kuò)展性和伸縮性,也拓展了系統(tǒng)整體的使用價(jià)值舔庶。
1 模塊解耦
實(shí)現(xiàn)服務(wù)模塊之間解耦的方式有很多抛蚁,但是插件來說,其解耦的程度似乎更高惕橙,而且更靈活,可定制化钉跷、個(gè)性化更好弥鹦。
2 提升擴(kuò)展性和開放性
插件化機(jī)制讓系統(tǒng)的擴(kuò)展性得以提升,從而可以豐富系統(tǒng)的周邊應(yīng)用生態(tài)爷辙。
3 方便第三方接入
有了插件之后彬坏,第三方應(yīng)用或系統(tǒng)如果要對(duì)接自身的系統(tǒng),直接基于系統(tǒng)預(yù)留的插件接口完成一套適合自己業(yè)務(wù)的實(shí)現(xiàn)即可膝晾,而且對(duì)自身系統(tǒng)的侵入性很小栓始,甚至可以實(shí)現(xiàn)基于配置參數(shù)的熱加載,方便靈活血当,開箱即用幻赚。
最佳實(shí)踐
- 面向接口編程
- 方法粒度足夠細(xì)(對(duì)應(yīng)一個(gè)功能點(diǎn))禀忆,方法異常能夠區(qū)分