Spring學(xué)習(xí)之依賴注入的方法(三種)
spring框架為我們提供了三種注入方式,分別是set注入,構(gòu)造方法注入,接口注入。今天就和大家一起來學(xué)習(xí)一下
依賴注入的基本概念
依賴注入(Dependecy Injection),也稱為IoC(Invert of Control),是一種有別于傳統(tǒng)的面向?qū)ο箝_發(fā)的思想,主要用于對(duì)應(yīng)用進(jìn)行解耦。簡(jiǎn)單的理解就是說,本來是由應(yīng)用服務(wù)自己創(chuàng)建的對(duì)象,數(shù)據(jù),交給第三方來負(fù)責(zé)創(chuàng)建,準(zhǔn)備,并且由第三方將對(duì)應(yīng)的內(nèi)容注入到應(yīng)用服務(wù)中來,從而實(shí)現(xiàn)了對(duì)象的創(chuàng)建于對(duì)象的應(yīng)用之間的解耦,通過這種方式,應(yīng)用服務(wù)可以最小程度地減少與對(duì)象實(shí)體之前的關(guān)聯(lián)(只需要使用即可,而不關(guān)心其來源,對(duì)應(yīng)的實(shí)現(xiàn)等等),從而保持了應(yīng)用服務(wù)與對(duì)象之間的弱耦合關(guān)系。
依賴注入的簡(jiǎn)單實(shí)現(xiàn)
可能通過文字的表達(dá),對(duì)于依賴注入不是很好理解,不過,通過簡(jiǎn)單的代碼實(shí)現(xiàn),就可以很輕松的理解了,下面通過原始的做法以及依賴注入的做法來進(jìn)行對(duì)比,來加深對(duì)依賴注入的理解
/** * 日志服務(wù) */ class LogService{ // 注意這里,這里是手動(dòng)創(chuàng)建對(duì)應(yīng)的LogDao實(shí)例對(duì)象 private LogDao logDao = new DBLogDao(); public void save(){ logDao.save(); } } /** * 日志DAO接口 */ interface LogDao{ void save(); } /** * 日志DAO的具體實(shí)現(xiàn),將日志保存到數(shù)據(jù)庫(kù)中 */ class DBLogDao implements LogDao{ @Override public void save() { System.out.println("Save to Database"); } }
從上面的代碼中可以看到,當(dāng)需要LogDao對(duì)象的時(shí)候,是直接在服務(wù)中創(chuàng)建具體的實(shí)現(xiàn),也就是new DBLogDao(),這種方式雖然方便,但是存在一定的缺點(diǎn),比如說,當(dāng)想要切換對(duì)應(yīng)的實(shí)現(xiàn),比如說XMLLogDao的時(shí)候,就需要打開對(duì)應(yīng)的代碼,創(chuàng)建XMLLogDao對(duì)象,并且將其交給LogService;而且,如果LogDao的創(chuàng)建過程比較繁瑣的時(shí)候,LogService在這種實(shí)現(xiàn)方式中,就需要知道LogDao的實(shí)現(xiàn)過程,而這顯然是不太合理的,因?yàn)長(zhǎng)ogService只需要知道LogDao的存在,以及使用方式即可,而并不需要知道它的創(chuàng)建過程。
接下來來看下依賴注入或者說控制反轉(zhuǎn)是怎么解決這些問題的。
class LogService{ // 注意這里,這里并沒創(chuàng)建對(duì)應(yīng)的對(duì)象 private LogDao logDao; // 通過屬性將LogDao注入到LogService中,這也就是依賴注入的來源 // 依賴別人講所需要的對(duì)象注入進(jìn)來 public void setLogDao(LogDao logDao) { this.logDao = logDao; } public void save(){ logDao.save(); } } // LogDao接口及其實(shí)現(xiàn)DBLogDao同上,這里省略 /** * 模擬的容器類,負(fù)責(zé)創(chuàng)建各個(gè)對(duì)象,并且將對(duì)應(yīng)的依賴對(duì)象注入進(jìn)去 */ class Container{ public void create(){ // 創(chuàng)建對(duì)象 LogService logService = new LogService(); LogDao logDao = new DBLogDao(); // 注入LogDao對(duì)象 logService.setLogDao(logDao); } }
可能這里你會(huì)覺得說,create方法中也是手動(dòng)創(chuàng)建了DBLogDao對(duì)象,其實(shí)不然,對(duì)于create方法來說,它只是負(fù)責(zé)創(chuàng)建對(duì)象,并不管對(duì)象的用途,也就是說,這里create方法可以通過各種其他手段,比如利用反射技術(shù),再通過配置文件來配置對(duì)應(yīng)的類的信息,這樣,當(dāng)需要修改具體的實(shí)現(xiàn)的時(shí)候,只需要修改配置文件,create就會(huì)創(chuàng)建對(duì)應(yīng)的對(duì)象,并且將其注入到LogService中,而這個(gè)過程對(duì)于LogService來說是透明的,LogService只知道自己有一個(gè)LogDao的對(duì)象,而不知道,也不需要知道LogDao對(duì)象是怎么來的。也就是實(shí)現(xiàn)了創(chuàng)建與使用的解耦。
至于控制反轉(zhuǎn)名詞,其實(shí)也是很顯然的嘛,本來是LogService自己創(chuàng)建的對(duì)象,現(xiàn)在將其交給Container來創(chuàng)建了,那么創(chuàng)建對(duì)象的權(quán)限不就是反轉(zhuǎn)了嘛^_^
一般來說,依賴注入有三種方式,分別是屬性注入,也就是上面我們看到的內(nèi)容,還有一種是構(gòu)造器注入,也就是通過構(gòu)造器注入對(duì)應(yīng)的對(duì)象,還有一種不常用的接口注入,其實(shí)本質(zhì)上也是屬于屬性注入。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
java 查找list中重復(fù)數(shù)據(jù)實(shí)例詳解
這篇文章主要介紹了java 查找list中重復(fù)數(shù)據(jù)實(shí)例詳解的相關(guān)資料,需要的朋友可以參考下2017-01-01Java學(xué)習(xí)基礎(chǔ)之安裝JDK/配置JDK環(huán)境&IEDA工具安裝
這篇文章主要介紹了Java學(xué)習(xí)基礎(chǔ)系列文章的第一篇,主要內(nèi)容是安裝JDK/配置JDK環(huán)境&IEDA工具安裝的相關(guān)資料,需要的朋友可以參考下2020-02-02SpringBoot生產(chǎn)環(huán)境打包如何去除無用依賴
這篇文章主要介紹了SpringBoot生產(chǎn)環(huán)境打包如何去除無用依賴問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-09-09基于SpringBoot實(shí)現(xiàn)自動(dòng)裝配返回屬性的設(shè)計(jì)思路
這篇文章主要介紹了基于SpringBoot實(shí)現(xiàn)自動(dòng)裝配返回屬性,這里涉及到的技術(shù)知識(shí)點(diǎn)有注解解析器,為什么用ResponseBodyAdvice這里解析?不在Filter,Interceptors,本文結(jié)合示例代碼給大家介紹的非常詳細(xì),需要的朋友參考下吧2022-03-03Java使用跳轉(zhuǎn)結(jié)構(gòu)實(shí)現(xiàn)隊(duì)列和棧流程詳解
這篇文章主要介紹了Java使用跳轉(zhuǎn)結(jié)構(gòu)實(shí)現(xiàn)隊(duì)列和棧流程,連續(xù)結(jié)構(gòu)和跳轉(zhuǎn)結(jié)構(gòu)是數(shù)據(jù)結(jié)構(gòu)中常見的兩種基本數(shù)據(jù)結(jié)構(gòu),而我們本次的主角棧和隊(duì)列都 既可以使用使用跳轉(zhuǎn)結(jié)構(gòu)實(shí)現(xiàn)也可以使用連續(xù)結(jié)構(gòu)實(shí)現(xiàn)2023-04-04