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