EJB 3.0 引入註解式依賴注入,大幅簡化 Bean 間引用。本文通過完整範例解析 @EJB 的屬性注入、Setter 注入、beanName 與 mappedName 的差異。
Bean1、Bean2、Bean3:遠端介面Bean1Impl:實作 Bean1/Bean2,JNDI 名 bean12Bean2Impl:實作 Bean3,注入 Bean1/Bean2bean3/remote 呼叫// 介面
@Remote public interface Bean1 { void sayBean1(); }
@Remote public interface Bean2 { void sayBean2(); }
@Remote public interface Bean3 { void sayBean3(); }
// Bean1Impl 實作 Bean1 & Bean2
@Stateless(name="bean12")
public class Bean1Impl implements Bean1, Bean2 {
public void sayBean1() { System.out.println("bean1........."); }
public void sayBean2() { System.out.println("bean2........."); }
}
// Bean2Impl 實作 Bean3,注入 Bean1 & Bean2
@Stateless(name="bean3")
public class Bean2Impl implements Bean3 {
@EJB(beanName="bean12") Bean1 bean1; // 屬性注入
@EJB(beanName="bean12") Bean2 bean2; // 同名不同介面
@EJB(mappedName="bean12/remote") // Setter 注入,指定 JNDI 名
public void setBean2(Bean2 bean2) { this.bean2 = bean2; }
public void sayBean3() {
bean1.sayBean1();
bean2.sayBean2();
System.out.println("bean3.........");
}
}
Properties props = new Properties();
props.setProperty("java.naming.factory.initial", "org.jnp.interfaces.NamingContextFactory");
props.setProperty("java.naming.provider.url", "localhost:1099");
props.setProperty("java.naming.factory.url.pkgs", "org.jboss.naming");
Context ctx = new InitialContext(props);
Bean3 bean = (Bean3) ctx.lookup("bean3/remote");
bean.sayBean3();
bean1.........
bean2.........
bean3.........
| 屬性 | 用途 | 範例值 |
|---|---|---|
beanName | 指定目標 Bean 的 @Stateless(name=...) 名稱 | bean12 |
mappedName | 指定目標 Bean 的全域 JNDI 名稱 | bean12/remote |
| 注入位置 | 欄位 / Setter 方法 | 均支援 |
| 範圍限制 | 僅限本地命名服務 | 無法注入遠端伺服器物件 |
實務建議:優先使用
beanName(邏輯名稱),避免硬編碼 JNDI 路徑,提升可移植性。