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

Struts + Spring + Hibernate 整合實戰:三層架構解耦與依賴注入裝配指南

     編輯:J2EE

背景動機:為什麼需要框架整合?

單一框架解決單一層面問題,企業級應用需表現層、業務層、持久層協同。整合目標:

  • 鬆耦合:各層通過接口交互,實現可替換
  • 關注點分離:Action 僅處理請求/響應,Service 承載業務/事務,DAO 封裝數據訪問
  • 聲明式中間件服務:事務、安全、資源管理交給容器/框架
  • 消除樣板代碼:模板類、異常轉換、資源管理自動化

領域模型層:跨層流轉的核心對象


// com.meagle.bo.Order.java
public class Order implements Serializable {
    private Integer id;
    private String username;
    private BigDecimal total;
    private Set lineItems = new HashSet<>(); // 一對多
    // 標準 Getter/Setter、equals/hashCode
}

// com.meagle.bo.OrderLineItem.java
public class OrderLineItem implements Serializable {
    private Integer id;
    private Order order; // 多對一反向引用
    private Product product;
    private Integer quantity;
    private BigDecimal price;
    // Getter/Setter
}

包命名規範:com.meagle.bo (領域對象)、com.meagle.service (業務接口/實現)、com.meagle.service.dao.hibernate (DAO 實現)、com.meagle.action/forms (表現層)。

持久層配置:Hibernate 映射與 SessionFactory

映射文件 (HBM XML / 註解)




    
    
    
    
        
        
    




    
    
    
    
    

Spring 整合 Hibernate SessionFactory




    
    
     
     
    



    
    
        
            com/meagle/bo/Order.hbm.xml
            com/meagle/bo/OrderLineItem.hbm.xml
        
    
    
        
            org.hibernate.dialect.MySQLDialect
            false
            update
        
    




    

業務層裝配:Spring IoC + AOP 事務

DAO 接口與實現


// 接口
public interface IOrderDAO {
    Order findById(Integer id);
    List findByUsername(String username);
    Order save(Order order);
}

// 實現 (繼承 HibernateDaoSupport 獲得 getHibernateTemplate())
public class OrderHibernateDAO extends HibernateDaoSupport implements IOrderDAO {
    public Order findById(Integer id) {
        return (Order) getHibernateTemplate().get(Order.class, id);
    }
    public List findByUsername(String username) {
        return getHibernateTemplate().find("FROM Order o WHERE o.username=?", username);
    }
    public Order save(Order order) {
        getHibernateTemplate().saveOrUpdate(order);
        return order;
    }
}

Service 接口與實現


// 接口
public interface IOrderService {
    Order saveNewOrder(Order order) throws OrderException, OrderMinimumAmountException;
    List findOrdersByUser(String user) throws OrderException;
    Order findOrderById(Integer id) throws OrderException;
    void setOrderDAO(IOrderDAO orderDAO); // Setter 注入
}

// 實現
public class OrderServiceSpringImpl implements IOrderService {
    private IOrderDAO orderDAO;
    public void setOrderDAO(IOrderDAO orderDAO) { this.orderDAO = orderDAO; }
    
    public Order saveNewOrder(Order order) throws OrderException, OrderMinimumAmountException {
        // 業務驗證
        if (order.getTotal().compareTo(new BigDecimal("100")) < 0) {
            throw new OrderMinimumAmountException("訂單金額不足 100 元");
        }
        return orderDAO.save(order);
    }
    // 其他方法委託 DAO...
}

聲明式事務配置 (核心亮點)




    
      // 目標業務 Bean
    
        
            PROPAGATION_REQUIRED,readOnly,-OrderException
            PROPAGATION_REQUIRED,-OrderException
        
    




      // 注入 DAO



    

事務屬性解讀:PROPAGATION_REQUIRED (支持當前事務/新建)、readOnly (優化標記)、-OrderException (遇到此異常回滾,繼承 RuntimeException 的異常默認回滾,Checked Exception 需顯式指定)。

表現層整合:Struts Action + 服務定位器

基礎 Action 類 (服務定位器模式)


public abstract class BaseAction extends Action {
    private IOrderService orderService;
    
    public void setServlet(ActionServlet actionServlet) {
        super.setServlet(actionServlet);
        ServletContext sc = actionServlet.getServletContext();
        WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext(sc);
        this.orderService = (IOrderService) wac.getBean("orderService"); // 從 Spring 容器獲取
    }
    
    protected IOrderService getOrderService() { return orderService; }
}

具體 Action 實現


public class SaveNewOrderAction extends BaseAction {
    public ActionForward execute(ActionMapping mapping, ActionForm form,
                                 HttpServletRequest request, HttpServletResponse response) throws Exception {
        OrderForm oForm = (OrderForm) form;
        // Form → Domain Object 轉換 (Action 職責)
        Order order = new Order();
        order.setUsername(oForm.getUsername());
        order.setTotal(oForm.getTotal());
        // lineItems 轉換...
        
        // 委託業務層
        getOrderService().saveNewOrder(order);
        
        // 結果傳遞
        oForm.setOrder(order);
        ActionMessages msgs = new ActionMessages();
        msgs.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("message.order.saved.successfully"));
        saveMessages(request, msgs);
        
        return mapping.findForward("success");
    }
}

Struts 配置 (struts-config.xml)



    
    
    
    

異常映射:業務層拋出的 Checked Exception 直接在 Struts 配置中映射到錯誤頁,Action 代碼零 try-catch,極其乾淨。

整合架構圖解


+------------------+     +--------------------------+     +--------------------------+     +--------------------------+
|   Struts Action  |---->|   Spring Service (Tx)    |---->|   Hibernate DAO          |---->|   Database               |
|  (Presentation)  |     |  (Business Logic/Valid)  |     |  (Persistence/O-R Map)   |     |  (MySQL/Oracle)          |
+------------------+     +--------------------------+     +--------------------------+     +--------------------------+
        |                         |                              |                              |
        | Form Bean              | Domain Object (POJO)         | Domain Object (POJO)         | Tables
        | Validation             | Transaction Boundary         | HibernateTemplate              |
        | Forward/Redirect       | Exception Translation        | Session Management             |
        +-------------------------+------------------------------+------------------------------+
                              |
                     Spring Container (IoC/AOP)
                     - Bean Wiring
                     - Transaction Proxy
                     - Resource Management

替換靈活性驗證

替換場景影響範圍操作步驟
Hibernate → iBATIS/MyBatis僅 DAO 實現1. 實現 IOrderDAO 接口 2. Spring 配置替換 orderDAO Bean 3. 移除 Hibernate 依賴
Struts → Spring MVC表現層1. Controller 替換 Action 2. 服務定位器改為 @Autowired 3. 移除 Struts 依賴
Spring 事務 → JTA (WebLogic)事務配置1. 替換 transactionManager Bean 為 JtaTransactionManager 2. 移除 HibernateTransactionManager
MySQL → Oracle數據源/方言1. 修改 dataSource URL/驅動 2. 修改 hibernate.dialect 3. 調整映射類型

總結:整合最佳實踐清單

  1. [ ] 領域模型 (POJO) 獨立於框架,無注解污染 (或僅 JPA 註解)
  2. [ ] DAO 接口定義在 service.dao 包,實現隔離在 dao.hibernate/ibatis 包
  3. [ ] Service 接口定義業務契約,Checked Exception 表達業務失敗
  4. [ ] Spring 管理所有 Bean 生命周期,TransactionProxyFactoryBean / @Transactional 聲明式事務
  5. [ ] Struts Action 僅做:Form→Domain、委託 Service、異常映射、Forward
  6. [ ] 服務定位器 / ContextLoaderListener / ContextLoaderPlugin 整合 Web 與 Spring 容器
  7. [ ] 異常體系:DAOException → ServiceException (Checked) → Struts Exception Mapping
  8. [ ] 配置文件模塊化:applicationContext-hibernate.xml, applicationContext-service.xml, applicationContext-web.xml
  9. [ ] 單元測試:Spring TestContext 框架注入 Service/DAO,無容器測試業務邏輯

「整合不是疊加,而是邊界的精確劃分與契約的嚴格遵守。Struts 做表現、Spring 做業務編排與事務、Hibernate 做對象持久化——各司其職,鬆耦合,高內聚,這才是框架整合的藝術。」

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