EJB 2.x 被廣泛詬病:樣板代碼多、Home/Remote 接口繁瑣、Entity Bean 複雜度高、部署描述符龐大。EJB 3.0 (JSR 220) 以「極簡開發」為目標,引入 Java 5 註解、採納 Hibernate O/R 映射模型,實現「配置即代碼」,大幅降低開發門檻。
EntityManager 管理生命週期,支援脫管/合併,O/R 映射採用 Hibernate 風格註解,EJB QL 大幅增強接近 SQL。@Stateless
@Remote
public class HelloWorldBean {
public String sayHello() { return "Hello World!!!"; }
}
@BusinessMethod 精確暴露方法)。@Remote 切換為遠程。@Init 註解)。@Remove 標記銷毀方法,調用後實例移除(異常情況下移除語義仍在討論)。javax.jms.MessageListener(或其他消息系統接口),此接口非傳統業務接口,僅標識消息類型。@Entity
@Table(name="CUSTOMER")
public class Customer {
@Id @GeneratedValue(strategy=GenerationType.AUTO)
private Long id;
private String name;
// getter/setter 或 public/protected 字段均可
}
@Entity 標記持久化實體,字段預設持久化,@Transient 排除。@OneToOne/@OneToMany/@ManyToOne/@ManyToMany,雙向關係需指定 mappedBy(inverse side)。@Column(name="DATA", columnDefinition="BLOB NOT NULL")
private byte[] data;
支援 columnDefinition 直接寫 SQL 片段,但作者建議謹慎使用,避免代碼與特定 SQL 方言緊耦合。
DELETE FROM Customer c WHERE c.status = 'inactive'JOIN/LEFT JOIN/FETCH JOINSELECT new CustomerDTO(c.id, c.name) FROM Customer cGROUP BY/HAVING、子查詢、原生 SQL (createNativeQuery)@NamedQuery(name="findByName", queryString="SELECT c FROM Customer c WHERE c.name LIKE :name")@Resource(name="myDataSource")
private DataSource customerDB; // 類型從字段推斷
@PersistenceContext
private EntityManager em; // 注入持久化上下文
@EJB
private PaymentService payment; // 注入 Session Bean
@Inject (JSR 299 前身) 簡化注入,但普通 Java 客戶端如何獲取上下文仍在規範討論中。CreateException/FinderException 等受檢異常。EJBException(非受檢)。@Persistent 替代 @Transient 明確標記持久化字段。columnDefinition 等 SQL 片段耦合度過高;原生 SQL 支援應規範用法,避免硬編碼;客戶端編程模型(特別是非受管客戶端)急需明確規範;@Table 執行時表名驗證機制需標準化。@SecurityRoles vs @MethodPermissions)、@RunAs 定義上有差異,最終將在 J2EE 5 層面統一。EJB 3.0 朝著「簡單、標準、POJO 化」邁出關鍵一步。O/R 映射模型仍在完善中,期望不與 SQL 過度耦合。開發者應積極向 ejb3-feedback@sun.com 提交建議,推動規範走向成熟。
原文作者:Itzealot(技術博客轉載)