淺析springboot通過(guò)面向接口編程對(duì)控制反轉(zhuǎn)IOC的理解
IoC是什么
Ioc—Inversion of Control,即“控制反轉(zhuǎn)”,不是什么技術(shù),而是一種設(shè)計(jì)思想。在Java開發(fā)中,Ioc意味著將你設(shè)計(jì)好的對(duì)象交給容器控制,而不是傳統(tǒng)的在你的對(duì)象內(nèi)部直接控制。如何理解好Ioc呢?理解好Ioc的關(guān)鍵是要明確“誰(shuí)控制誰(shuí),控制什么,為何是反轉(zhuǎn)(有反轉(zhuǎn)就應(yīng)該有正轉(zhuǎn)了),哪些方面反轉(zhuǎn)了”,那我們來(lái)深入分析一下:
●誰(shuí)控制誰(shuí),控制什么:傳統(tǒng)Java SE程序設(shè)計(jì),我們直接在對(duì)象內(nèi)部通過(guò)new進(jìn)行創(chuàng)建對(duì)象,是程序主動(dòng)去創(chuàng)建依賴對(duì)象;而IoC是有專門一個(gè)容器來(lái)創(chuàng)建這些對(duì)象,即由Ioc容器來(lái)控制對(duì) 象的創(chuàng)建;誰(shuí)控制誰(shuí)?當(dāng)然是IoC 容器控制了對(duì)象;控制什么?那就是主要控制了外部資源獲?。ú恢皇菍?duì)象包括比如文件等)。
●為何是反轉(zhuǎn),哪些方面反轉(zhuǎn)了:有反轉(zhuǎn)就有正轉(zhuǎn),傳統(tǒng)應(yīng)用程序是由我們自己在對(duì)象中主動(dòng)控制去直接獲取依賴對(duì)象,也就是正轉(zhuǎn);而反轉(zhuǎn)則是由容器來(lái)幫忙創(chuàng)建及注入依賴對(duì)象;為何是反轉(zhuǎn)?因?yàn)橛扇萜鲙臀覀儾檎壹白⑷胍蕾噷?duì)象,對(duì)象只是被動(dòng)的接受依賴對(duì)象,所以是反轉(zhuǎn);哪些方面反轉(zhuǎn)了?依賴對(duì)象的獲取被反轉(zhuǎn)了。
IoC能做什么
IoC 不是一種技術(shù),只是一種思想,一個(gè)重要的面向?qū)ο缶幊痰姆▌t,它能指導(dǎo)我們?nèi)绾卧O(shè)計(jì)出松耦合、更優(yōu)良的程序。傳統(tǒng)應(yīng)用程序都是由我們?cè)陬悆?nèi)部主動(dòng)創(chuàng)建依賴對(duì)象,從而導(dǎo)致類與類之間高耦合,難于測(cè)試;有了IoC容器后,把創(chuàng)建和查找依賴對(duì)象的控制權(quán)交給了容器,由容器進(jìn)行注入組合對(duì)象,所以對(duì)象與對(duì)象之間是 松散耦合,這樣也方便測(cè)試,利于功能復(fù)用,更重要的是使得程序的整個(gè)體系結(jié)構(gòu)變得非常靈活。
其實(shí)IoC對(duì)編程帶來(lái)的最大改變不是從代碼上,而是從思想上,發(fā)生了“主從換位”的變化。應(yīng)用程序原本是老大,要獲取什么資源都是主動(dòng)出擊,但是在IoC/DI思想中,應(yīng)用程序就變成被動(dòng)的了,被動(dòng)的等待IoC容器來(lái)創(chuàng)建并注入它所需要的資源了。
IoC很好的體現(xiàn)了面向?qū)ο笤O(shè)計(jì)法則之一—— 好萊塢法則:“別找我們,我們找你”;即由IoC容器幫對(duì)象找相應(yīng)的依賴對(duì)象并注入,而不是由對(duì)象主動(dòng)去找。
好了,正文開始!
IOC,把控制反轉(zhuǎn)到業(yè)務(wù)端,這句話沒(méi)什么問(wèn)題,在springboot框架里,對(duì)象的管理是通過(guò)spring ioc來(lái)實(shí)現(xiàn)的,而開發(fā)人員的開發(fā)原則里總是說(shuō)“面向接口編程”,而為什么要面向接口卻沒(méi)幾個(gè)人能說(shuō)出來(lái),今天在寫一個(gè)基于redis的手動(dòng)分布鎖時(shí),對(duì)這個(gè)面向接口和控制反轉(zhuǎn)又有了一個(gè)體會(huì)。
底層代碼更需要面向接口
當(dāng)你為開發(fā)人員提供一個(gè)封閉的包時(shí),他們是直接用的,他們不會(huì)修改你的代碼,當(dāng)然他們可以去繼承并擴(kuò)展;當(dāng)然如果你不希望被繼承可以聲明為final
,這都是面向?qū)ο缶幊汤锾峁┖玫墓δ?,我們主要?code>控制反轉(zhuǎn)這句話,它把控制權(quán)交給了上層去實(shí)現(xiàn),底層通過(guò) 面向接口
的原則只設(shè)計(jì)一個(gè)規(guī)范,而又使用者去實(shí)現(xiàn);但框架功能里的細(xì)節(jié)是要有的,這類似于“模版方法”模式,底層框架實(shí)現(xiàn)了流程,而個(gè)性化的部分由上層去實(shí)現(xiàn)。
看jpa里的審計(jì)接口
public interface AuditorAware<T> { /** * Returns the current auditor of the application. * * @return the current auditor */ Optional<T> getCurrentAuditor(); }
上面這個(gè)泛型接口只有一個(gè)方法,需要讓上層開發(fā)人員根據(jù)自己的業(yè)務(wù)去實(shí)現(xiàn)它,比較返回一個(gè)當(dāng)前登陸的用戶實(shí)體,或者返回用戶名稱,然后底層框架里直接使用這個(gè)AuditorAware接口的對(duì)象;當(dāng)然如果你的底層只接收一個(gè)String類型的值,你也可以去派生一個(gè)個(gè)性化接口,讓上層開發(fā)人員去實(shí)現(xiàn)你的接口即可。
/** * 返回用戶ID的標(biāo)識(shí)接口,由程序使用者去實(shí)現(xiàn). */ public interface UserIdAuditorAware extends AuditorAware<String> { }
上面代碼更加準(zhǔn)確的規(guī)定了AuditorAware是一個(gè)字符串的接口,只返回用戶ID即可。
@Component public class CurrentUserAware implements UserIdAuditorAware { @Autowired ApplicationContext applicationContext; @Override public Optional<String> getCurrentAuditor() { ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); HttpServletRequest request = requestAttributes.getRequest(); return Optional.of(request.getSession().getAttribute("id").toString()); } }
我們的底層代碼會(huì)使用它的getCurrentAuditor()
返回值 ,它是一個(gè)字符串。
public Object execute(String sourceId, Integer timeout, TimeUnit unit) { Assert.notNull(sourceId, "sourceId不能為空"); String key = getKey(sourceId); String user = auditorAware.getCurrentAuditor().orElse(null); Assert.notNull(user, "AuditorAware實(shí)例返回的值為空"); // 代碼略 }
對(duì)于一個(gè)小小的功能,我們?cè)诮?jīng)過(guò)思考之后,對(duì)于之前學(xué)過(guò)的東西進(jìn)行總結(jié),你可能會(huì)想法某種設(shè)計(jì)模式、某個(gè)算法、某個(gè)原則、在使用它們之后,讓你的代碼擴(kuò)展性更好,這種代碼也仿佛有了生命!
總結(jié)
到此這篇關(guān)于淺析springboot通過(guò)面向接口編程對(duì)控制反轉(zhuǎn)IOC的理解的文章就介紹到這了,更多相關(guān)springboot面向接口編程控制反轉(zhuǎn)IOC內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringMVC基于阻塞隊(duì)列LinkedBlockingQueue的同步長(zhǎng)輪詢功能實(shí)現(xiàn)詳解
這篇文章主要介紹了SpringMVC基于阻塞隊(duì)列LinkedBlockingQueue的同步長(zhǎng)輪詢功能實(shí)現(xiàn)詳解,本文介紹的也是生產(chǎn)者消費(fèi)者的一種實(shí)現(xiàn),生產(chǎn)者不必是一個(gè)始終在執(zhí)行的線程,它可以是一個(gè)接口,接受客戶端的請(qǐng)求,向隊(duì)列中插入消息,需要的朋友可以參考下2023-07-07java實(shí)現(xiàn)哈夫曼壓縮的實(shí)例
這篇文章主要介紹了java實(shí)現(xiàn)哈夫曼壓縮的實(shí)例的相關(guān)資料,需要的朋友可以參考下2017-07-07Java中的WeakHashMap概念原理以及簡(jiǎn)單案例
這篇文章主要介紹了Java中的WeakHashMap概念原理以及簡(jiǎn)單案例,WeakHashMap使用了軟引用結(jié)構(gòu),它的對(duì)象在垃圾回收時(shí)會(huì)被刪除,垃圾回收是優(yōu)先級(jí)非常低的線程,不能被顯示調(diào)用,當(dāng)內(nèi)存不足的時(shí)候會(huì)啟用,需要的朋友可以參考下2023-09-09SpringCloud HystrixDashboard服務(wù)監(jiān)控詳解
Hystrix Dashboard 是Spring Cloud中查看Hystrix實(shí)例執(zhí)行情況的一種儀表盤組件,支持查看單個(gè)實(shí)例和查看集群實(shí)例,本文將對(duì)其服務(wù)監(jiān)控學(xué)習(xí)2022-11-11mybatis?<foreach>標(biāo)簽動(dòng)態(tài)增刪改查方式
這篇文章主要介紹了mybatis?<foreach>標(biāo)簽動(dòng)態(tài)增刪改查方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-03-03詳解 問(wèn)題:HttpServlet cannot be resolved to a type
這篇文章主要介紹了詳解 問(wèn)題:HttpServlet cannot be resolved to a type的相關(guān)資料,需要的朋友可以參考下2017-03-03