首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

控制反轉與依賴注入:IoC/DI 核心原理、三種注入模式與好萊塢原則深度解析

     編輯:Java 相關知識

控制反轉是物件導向設計中解耦合的核心模式。傳統程式碼由呼叫端直接建立與管理依賴物件,IoC 將這項控制權移交給外部容器,實現元件裝配與生命週期的集中管理。依賴注入是 IoC 最主流的實現形式,讓容器全權負責依賴查詢與注入,受管元件僅暴露 setter、建構子或介面,達到與容器 API 完全解耦、易於單元測試與跨容器遷移的目標。

IoC 兩大實現路徑:依賴查找 vs 依賴注入

  • 依賴查找:容器提供回呼介面與上下文,元件主動查找依賴。EJB、Apache Avalon 採用此模式。程式碼耦合容器 API,難在容器外獨立運行。
  • 依賴注入:元件被動接受依賴,不進行定位查詢。容器在初始化時組裝依賴關係。優勢在於:查找邏輯與應用程式碼完全分離、不依賴容器 API、多數物件可做到零容器依賴。

好萊塢原則:「別打給我們,我們會打給你」

IoC 體現好萊塢原則。模板方法模式中,基類定義演算法骨架,具體步驟延遲至子類實現;IoC 容器定義流程框架,業務邏輯由外部物件注入參與。兩種參與方式:依賴查找(如 JNDI 主動查找)與依賴注入(容器推送)。

依賴查找程式碼示範

public class MyBusinessObject {
    private DataSource ds;
    private MyCollaborator myCollaborator;
    public MyBusinessObject() {
        Context ctx = null;
        try {
            ctx = new InitialContext();
            ds = (DataSource) ctx.lookup("java:comp/env/dataSourceName");
            myCollaborator = (MyCollaborator) ctx.lookup("java:comp/env/myCollaboratorName");
        } ...
    }
}

缺點顯而易見:程式碼強依賴 JNDI 環境,無法在應用伺服器外運行;更換查找方式需重構策略方法。

依賴注入三大模式完整實作

以 Content 為被注入的業務物件,MyBusiness 為接收端。

1. 建構子注入

public class MyBusiness {
    private Content myContent;
    public MyBusiness(Content content) { this.myContent = content; }
    public void doBusiness() { myContent.businessContent(); }
}

依賴在建構時強制注入,適合不可變依賴與必要依賴。

2. 設值注入

public class MyBusiness {
    private Content myContent;
    public void setContent(Content content) { this.myContent = content; }
    public void doBusiness() { myContent.businessContent(); }
}

依賴可變更、可選擇性注入,靈活度最高,最常用。

3. 介面注入

public interface InContent { void createContent(Content content); }
public class MyBusiness implements InContent {
    private Content myContent;
    public void createContent(Content content) { this.myContent = content; }
    public void doBusiness() { myContent.businessContent(); }
}

透過介面規範注入契約,容器調用介面方法完成注入,耦合度介於前兩者之間。

依賴拉取:Spring 中的實用變體

public static void main(String[] args) {
    BeanFactory factory = getBeanFactory();
    MessageRender mr = (MessageRender) factory.getBean("renderer");
    mr.render();
}

從集中式 BeanFactory 獲取 Bean,本質區別於依賴查找:查找發生在啟動入口等特定集中位置,而非分散在業務元件內部。通常搭配 XML 配置實現物件集中管理。

掌握 IoC/DI 精髓,關鍵在於理解控制權轉移帶來的解耦價值,並根據依賴的必要性、可變性選擇建構子、設值或介面注入。Spring 等成熟容器已將這些模式封裝為聲明式配置,開發者專注於業務邏輯即可。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved