Spring學(xué)習(xí)之依賴注入

Spring學(xué)習(xí)之依賴注入

依賴注入的基本概念

依賴注入(Dependecy Injection),也稱為IoC(Invert of Control),是一種有別于傳統(tǒng)的面向?qū)ο箝_發(fā)的思想,主要用于對應(yīng)用進(jìn)行解耦。簡單的理解就是說,本來是由應(yīng)用服務(wù)自己創(chuàng)建的對象,數(shù)據(jù),交給第三方來負(fù)責(zé)創(chuàng)建,準(zhǔn)備,并且由第三方將對應(yīng)的內(nèi)容注入到應(yīng)用服務(wù)中來,從而實(shí)現(xiàn)了對象的創(chuàng)建于對象的應(yīng)用之間的解耦,通過這種方式,應(yīng)用服務(wù)可以最小程度地減少與對象實(shí)體之前的關(guān)聯(lián)(只需要使用即可,而不關(guān)心其來源,對應(yīng)的實(shí)現(xiàn)等等),從而保持了應(yīng)用服務(wù)與對象之間的弱耦合關(guān)系。

依賴注入的簡單實(shí)現(xiàn)

可能通過文字的表達(dá),對于依賴注入不是很好理解,不過,通過簡單的代碼實(shí)現(xiàn),就可以很輕松的理解了,下面通過原始的做法以及依賴注入的做法來進(jìn)行對比,來加深對依賴注入的理解

/**
* 日志服務(wù)
*/
class LogService{

    // 注意這里,這里是手動創(chuàng)建對應(yīng)的LogDao實(shí)例對象
    private LogDao logDao = new DBLogDao(); 

    public void save(){
        logDao.save();
    }
}

/**
*  日志DAO接口
*/
interface LogDao{

    void save();
}

/**
*  日志DAO的具體實(shí)現(xiàn),將日志保存到數(shù)據(jù)庫中
*/
class DBLogDao implements LogDao{

    @Override
    public void save() {
        System.out.println("Save to Database");
    }
}

從上面的代碼中可以看到,當(dāng)需要LogDao對象的時候,是直接在服務(wù)中創(chuàng)建具體的實(shí)現(xiàn),也就是new DBLogDao(),這種方式雖然方便,但是存在一定的缺點(diǎn),比如說,當(dāng)想要切換對應(yīng)的實(shí)現(xiàn),比如說XMLLogDao的時候,就需要打開對應(yīng)的代碼,創(chuàng)建XMLLogDao對象,并且將其交給LogService;而且,如果LogDao的創(chuàng)建過程比較繁瑣的時候,LogService在這種實(shí)現(xiàn)方式中,就需要知道LogDao的實(shí)現(xiàn)過程,而這顯然是不太合理的,因?yàn)長ogService只需要知道LogDao的存在,以及使用方式即可,而并不需要知道它的創(chuàng)建過程。

接下來來看下依賴注入或者說控制反轉(zhuǎn)是怎么解決這些問題的。


class LogService{

    // 注意這里,這里并沒創(chuàng)建對應(yīng)的對象
    private LogDao logDao;

    // 通過屬性將LogDao注入到LogService中,這也就是依賴注入的來源
    // 依賴別人講所需要的對象注入進(jìn)來
    public void setLogDao(LogDao logDao) {
        this.logDao = logDao;
    }

    public void save(){
        logDao.save();
    }
}

// LogDao接口及其實(shí)現(xiàn)DBLogDao同上,這里省略

/**
* 模擬的容器類,負(fù)責(zé)創(chuàng)建各個對象,并且將對應(yīng)的依賴對象注入進(jìn)去
*/
class Container{

    public void create(){
        
        // 創(chuàng)建對象
        LogService logService = new LogService();
        LogDao logDao = new DBLogDao();

        // 注入LogDao對象
        logService.setLogDao(logDao);
    }
}

可能這里你會覺得說,create方法中也是手動創(chuàng)建了DBLogDao對象,其實(shí)不然,對于create方法來說,它只是負(fù)責(zé)創(chuàng)建對象,并不管對象的用途,也就是說,這里create方法可以通過各種其他手段,比如利用反射技術(shù),再通過配置文件來配置對應(yīng)的類的信息,這樣,當(dāng)需要修改具體的實(shí)現(xiàn)的時候,只需要修改配置文件,create就會創(chuàng)建對應(yīng)的對象,并且將其注入到LogService中,而這個過程對于LogService來說是透明的,LogService只知道自己有一個LogDao的對象,而不知道,也不需要知道LogDao對象是怎么來的。也就是實(shí)現(xiàn)了創(chuàng)建與使用的解耦。

至于控制反轉(zhuǎn)名詞,其實(shí)也是很顯然的嘛,本來是LogService自己創(chuàng)建的對象,現(xiàn)在將其交給Container來創(chuàng)建了,那么創(chuàng)建對象的權(quán)限不就是反轉(zhuǎn)了嘛_

一般來說,依賴注入有三種方式,分別是屬性注入,也就是上面我們看到的內(nèi)容,還有一種是構(gòu)造器注入,也就是通過構(gòu)造器注入對應(yīng)的對象,還有一種不常用的接口注入,其實(shí)本質(zhì)上也是屬于屬性注入。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,654評論 19 139
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,209評論 25 708
  • Spring Boot 參考指南 介紹 轉(zhuǎn)載自:https://www.gitbook.com/book/qbgb...
    毛宇鵬閱讀 47,281評論 6 342
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法,內(nèi)部類的語法,繼承相關(guān)的語法,異常的語法,線程的語...
    子非魚_t_閱讀 34,745評論 18 399
  • 為全面了解掌握廣大職工身體健康狀況,預(yù)防和減少重大疾病發(fā)生,結(jié)合企業(yè)實(shí)際,統(tǒng)籌安排,歷經(jīng)2個月南方公司職工健康體檢...
    331杏子閱讀 592評論 0 0

友情鏈接更多精彩內(nèi)容