愛因斯坦名言「盡可能簡單,但不能過度簡化」精準概括企業軟體開發真諦。Spring 與 EJB 3.0 共同擁抱核心理念:將中介軟體服務(交易、安全、持久化)透明注入鬆耦合的 POJO。POJO 無需繼承框架類別或實作介面,開發者得以專注商業邏輯與脫容器單元測試,靈活構建繼承體系。
EJB 3.0:JCP 標準規範,全主流 J2EE 廠商支援。開發者與應用伺服器實作完全隔離(如 JBoss 基於 Hibernate、Oracle 基於 TopLink,開發者無需學習具體 API)。即便伺服器未原生支援,亦可嵌入式運行(如 JBoss Embeddable EJB3)。
Spring:非標準開源框架(Interface21 控制),雖可跨伺服器部署,但應用鎖定於 Spring 本身及整合的具體服務(如 Spring 交易管理器、Spring MVC)。長期生存度繫於專案/公司命運。
EJB 3.0:與應用伺服器深度整合,服務整合代碼封裝於標準介面後。廠商可極致優化效能與開發體驗。
範例:JBoss EJB 3.0 中 EntityManager 的 Hibernate Session 自動綁定 JTA 交易;@PersistenceContext 輕鬆實現跨多請求的應用交易(如多頁購物車)。叢集容錯、負載均衡、分散式快取、狀態複寫全自動透明化。
Spring:處於伺服器與服務庫上層,整合代碼(資料存取模板、輔助類)暴露於開發者。需手動 XML 配置 TransactionManager 與 SessionFactory,跨 HTTP 請求交易管理複雜,叢集負載均衡無標準方案。
Spring:整合代碼外露,開發者可按需組裝輕量級伺服器(如 Tomcat + Hibernate + Spring 交易 = 袖珍應用伺服器),利於脫容器單元測試(Mock 物件替換)。
EJB 3.0:典型提供打包特性集,彈性較小;模組化伺服器(如 JBoss)可裁剪。超過單機規模時,資源池、訊息佇列、叢集等企業級服務不可或缺,整體資源消耗與 Spring 相當。
測試策略差異:EJB 3.0 多數元件為 POJO,易脫容器測試;涉及容器服務(如 EntityManager)建議容器內測試,更簡單、健壯、準確。
Spring:以 XML 為主,表達複雜關係但冗長脆弱。
EJB 3.0:大量採用 Java 註解,簡潔直觀但難表達複雜/繼承關係。
架構驅動選擇:EJB 3.0 整合前置框架,註解足夠;Spring 作為通用 DI 容器需 XML 承載更多配置。兩者互補:EJB 3.0 以 XML 覆寫註解預設,Spring 亦支援註解配置服務。
EJB 3.0 註解風格:
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public void bar() { ... }
@SecurityDomain("other")
public class Foo {
@RolesAllowed({"managers"})
@TransactionAttribute(REQUIRED)
public void doBusiness() { ... }
}
Spring XML 風格:需在應用上下文定義切點、通知、交易屬性,配置量大幅較高。
在大多數情境下,EJB 3.0 註解對宣告式服務更簡潔明瞭。
選擇 Spring 還是 EJB 3.0,取決於團隊對標準化與廠商中立 vs 組合彈性與輕量部署的權衡。EJB 3.0 以標準化贏得長期保障與深度整合;Spring 以非標準換取極致組裝自由。理解雙方架構基因,方能做出最適技術決策。