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

EJB 3.0 簡化 Java 企業級開發(上):註解驅動、POJO 服務、依賴注入與容器服務聲明式接入

     編輯:Java 相關知識

前言:從「過於複雜」到「簡單即強大」

Java EE(原 J2EE)功能強大卻因過度複雜令人卻步。三年來,開源社區、JCP、主流廠商共同推動簡化:POJO 服務、服務攔截器、依賴注入、Hibernate、AOP、Spring 等成果湧現。簡化 ≠ 功能減少,而是將複雜邏輯下沉框架,對應用開發者隱形。研究表明:將示例應用從 EJB 2.1 遷移至 3.0,**代碼量減少 50%+**。Java 註解是核心鑰匙,將 POJO 服務、POJO 持久化、依賴注入綁定為完整中間件方案。

EJB 3.0 註解驅動編程模型

註解 vs XML:三大維度對比

維度XML 部署描述符Java 註解
冗長度極高(大量重復類名/方法名)低(代碼內嵌,無額外引用)
健壯性運行時才發現錯誤(拼寫、簽名不匹配)編譯期檢查,與代碼同步處理
靈活性高(部署期修改,不動代碼,運維友好)相對固化(需重編譯)

EJB 3.0 策略:註解配置 90% 應用,XML 覆蓋默認註解、配置外部資源(數據源等),兩全其美。

POJO vs 嚴格組件模型

  • EJB 2.x:組件必須繼承抽象類、實現回調接口、單繼承限制導致對象結構僵化
  • EJB 3.0:所有容器服務通過註解注入 POJO,無特殊基類,無接口強制,對象結構自由演化

開發鬆耦合服務組件

Session Bean:鬆耦合服務的標準形式

至少一個業務接口,其他組件通過接口獲取服務。實現類僅需 @Stateless 或 @Stateful 註解。

無狀態會話 Bean 範例:投資計算器

// 業務接口
public interface Calculator {
    double calculate(int startAge, int endAge, double growthRate, double monthlySaving);
}

// 實現類:POJO + @Stateless
@Stateless
public class CalculatorBean implements Calculator {
    public double calculate(int start, int end, double growthRate, double saving) {
        double factor = Math.pow(1 + growthRate/12, 12*(end-start)+1);
        return saving * 12 * (factor - 1) / growthRate;
    }
}

本地/遠程接口分離

@Stateless
@Local(Calculator.class)
@Remote(RemoteCalculator.class)
public class CalculatorBean implements Calculator, RemoteCalculator {
    // 實現兩個接口方法...
}

無註解默認為本地接口。

客戶端調用:JNDI 查找獲取 Stub

InitialContext ctx = new InitialContext();
Calculator cal = (Calculator) ctx.lookup(Calculator.class.getName());
double result = cal.calculate(start, end, growthRate, saving);

Stateful Bean 必須客戶端緩存 Stub,後續調用復用同一實例。

Session Bean 生命週期管理:控制反轉

創建、緩存、銷毀全權容器管理(IoC)。應用僅與業務接口交互。若需掛鉤生命週期,聲明回調方法並標註註解:

註解觸發時機適用類型
@PostConstruct實例化完成、依賴注入後Stateful / Stateless
@PreDestroy實例從池移除前Stateful / Stateless
@PrePassivateStateful 實例閒置超時將被鈍化前Stateful
@PostActivateStateful 實例激活完成後Stateful
@InitStateful 實例初始化(可多個,按創建方式匹配)Stateful
@Remove調用此方法後容器移除實例,終止會話Stateful

Stateful Bean 完整生命週期範例

@Stateful
public class CalculatorBean implements Calculator, Serializable {
    @PostConstruct
    public void initialize() {
        // 載入歷史記錄、初始化數據庫連接...
    }
    
    @PreDestroy
    public void exit() {
        // 保存歷史記錄至數據庫...
    }
    
    @Remove
    public void stopSession() {
        // 方法體可為空,調用即通知容器移除實例
    }
}

消息驅動 Bean:異步鬆耦合服務

處理基於消息的異步請求(Email、JMS)。實現 MessageListener,onMessage() 為入口。註解配置監聽隊列:

@MessageDriven(activationConfig = {
    @ActivationConfigProperty(propertyName="destinationType", propertyValue="javax.jms.Queue"),
    @ActivationConfigProperty(propertyName="destination", propertyValue="queue/mdb")
})
public class CalculatorMDB implements MessageListener {
    public void onMessage(Message msg) {
        try {
            TextMessage tmsg = (TextMessage) msg;
            // 解析參數、計算、記錄...
        } catch (Exception e) { e.printStackTrace(); }
    }
}

依賴注入:優雅解耦服務與資源

JNDI 查找痛點:字符串名稱無編譯檢查、類型轉換運行時風險、樣板代碼繁瑣。EJB 3.0 提供 @EJB、@Resource 註解聲明式注入:

@EJB 注入 Session Bean Stub

// 字段注入
public class CalculatorMDB implements MessageListener {
    @EJB Calculator cal;  // 容器首次訪問前自動賦值
    // 使用 cal...
}

// Setter 注入
public class CalculatorMDB implements MessageListener {
    private Calculator cal;
    @EJB
    public void setCal(Calculator cal) { this.cal = cal; }
}

@Resource 注入任意 JNDI 資源

@Resource TimerService timerService;
@Resource SessionContext sessionContext;
@Resource(name="DefaultDS") DataSource myDb;
@Resource(name="ConnectionFactory") QueueConnectionFactory factory;
@Resource(name="queue/A") Queue queue;

注入持久化上下文

@PersistenceContext EntityManager em; // 類似 Hibernate Session

將容器服務交給 POJO:聲明式事務與安全

事務管理:@TransactionAttribute

@Stateless
public class CalculatorBean implements Calculator {
    @TransactionAttribute(TransactionAttributeType.REQUIRED)
    public void updateExchangeRate(double newRate) throws Exception {
        // 循環更新數據庫,全成功或全回滾
    }
}

容器在合適事務上下文運行方法,方法內所有調用共享事務(除非另有聲明)。

安全服務:@SecurityDomain + @RolesAllowed / @PermitAll

@Stateless
@SecurityDomain("other")  // 指向 classpath 下 users.properties/roles.properties
public class CalculatorBean implements Calculator {
    @RolesAllowed("AdminUser")
    public void addFund(String name, double rate) { ... }
    
    @RolesAllowed("AdminUser")
    public void addInvestor(String name, int start, int end) { ... }
    
    @PermitAll
    public Collection getFunds() { ... }
    
    @RolesAllowed("AdminUser")
    public double calculate(int fundId, int investorId, double saving) { ... }
}

容器攔截調用,認證用戶,授權檢查,失敗拋出安全異常。

通用攔截器:擴展容器服務

事務、安全本質是容器管理的運行時攔截器。EJB 3.0 允許自定義攔截器:

@AroundInvoke
public Object log(InvocationContext ctx) throws Exception {
    long start = System.currentTimeMillis();
    try {
        return ctx.proceed(); // 執行目標方法
    } finally {
        System.out.println(ctx.getMethod() + " 耗時: " + (System.currentTimeMillis()-start) + "ms");
    }
}

攔截器方法可定義在 Bean 類、單獨攔截器類、或通過 XML 配置默認攔截器。

總結

EJB 3.0 以註解驅動、POJO 化、依賴注入、聲明式服務四大支柱,重塑了 Java 企業級開發體驗。開發者回歸業務邏輯,容器托管基礎設施,鬆耦合組件靈活組裝。這不僅是 EJB 的勝利,更是Spring 等開源創新回饋標準化的里程碑。

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