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

Spring 實戰(六):IOC 依賴注入構建 MVC 分層架構——Action/Service/DAO 解耦實踐

     編輯:Java 綜合教學

Spring 實戰(六):IOC 依賴注入構建 MVC 分層架構——Action/Service/DAO 解耦實踐

Spring IoC 容器的核心價值在於依賴注入(DI)實現元件間鬆耦合。本文以經典三層架構(Action → Service → DAO)為例,展示如何透過 XML 配置Setter 注入將介面綁定至實作、層層注入依賴,構建可測試、可擴展、易維護的分層應用。

一、分層介面定義

// DAO 層介面
public interface IStuDAO {
    void saveStu();
}

// Service 層介面
public interface IStuService {
    void saveStu();
}

二、實作類別與注入點

// DAO 實作
public class StuDAOImpl implements IStuDAO {
    @Override
    public void saveStu() {
        System.out.println("dao: saving stu...");
    }
}

// Service 實作——注入 DAO 介面
public class StuServiceImpl implements IStuService {
    private IStuDAO stuDAO; // 依賴介面,而非具體類
    
    @Override
    public void saveStu() {
        System.out.println("service: saving stu...");
        stuDAO.saveStu(); // 委派 DAO
    }
    
    // Setter 注入點
    public void setStuDAO(IStuDAO stuDAO) { this.stuDAO = stuDAO; }
    public IStuDAO getStuDAO() { return stuDAO; }
}

// Action/Controller——注入 Service 介面
public class PersonAction {
    private IStuService stuService; // 依賴介面
    
    public void displaySave() {
        System.out.println("mvc action: saving stu...");
        stuService.saveStu();
    }
    
    public void setStuService(IStuService stuService) { this.stuService = stuService; }
    public IStuService getStuService() { return stuService; }
}

三、Spring XML 配置:層層注入

<beans ...>
    <!-- Action 層:注入 Service -->
    <bean id="personAction" class="com.lee.spring008.IOC.DI.MVC.PersonAction">
        <property name="stuService" ref="stuService"/>
    </bean>

    <!-- Service 層:注入 DAO -->
    <bean id="stuService" class="com.lee.spring008.IOC.DI.MVC.StuServiceImpl">
        <property name="stuDAO" ref="stuDAO"/>
    </bean>

    <!-- DAO 層:無依賴 -->
    <bean id="stuDAO" class="com.lee.spring008.IOC.DI.MVC.StuDAOImpl"/>
</beans>

配置解析:

  • `ref="stuService"`:引用容器中 `id="stuService"` 的 Bean 實例注入 `personAction.stuService`。
  • 容器啟動順序:先實例化 `stuDAO` → `stuService`(注入 `stuDAO`) → `personAction`(注入 `stuService`)。
  • 所有依賴指向介面,實作類可隨時替換(如測試用 Mock、切換資料庫實作),零修改業務代碼。

四、單元測試驗證

@Test
public void testPersonAction() {
    ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
    PersonAction person = (PersonAction) context.getBean("personAction");
    person.displaySave();
}

輸出結果

mvc action: saving stu...
service: saving stu...
dao: saving stu...

五、Setter 注入 vs 構造器注入對比

維度Setter 注入構造器注入
可讀性屬性名明確,XML 易讀參數順序需對應建構子,較隱晦
不可變性物件建立後可修改依賴建構子注入後不可變,執行緒安全
循環依賴支援(需配合 `lazy-init`)不支援,啟動拋異常
強制依賴無法強制,易漏注入導致 NPE建構子參數天然強制,編譯期保證
建議場景可選依賴、多屬性、需重新配置核心強制依賴、不可變物件、不可變依賴圖

現代 Spring 最佳實踐:核心依賴用構造器注入(`@Autowired` 建構子),可選依賴用 Setter/Field 注入。Spring 4.3+ 單一建構子可省略 `@Autowired`。

六、進階:介面隔離與測試替換

// 測試配置:替換 DAO 為 Mock 實作
<bean id="stuDAO" class="com.lee.test.MockStuDAO"/> 
// 原 Service、Action 代碼零修改,自動注入 Mock,驗證邏輯隔離

七、原始碼獲取

完整專案結構:

https://github.com/leechenxiang/maven-spring001-helloworld

結語

透過 Spring IoC 容器管理 `Action → Service → DAO` 依賴圖,配合介面導向設計與Setter/構造器注入,實現了各層編譯期、執行期雙重解耦。這不僅支援單元測試的 Mock 替換,更為未來微服務拆分、多資料源切換、AOP 橫切關注點植入奠定堅實基礎。掌握 DI 配置細節與選型原則,是 Spring 開發者進階的必修課。

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