Spring IOC (Inversion of Control) 與 EJB 3 Session Bean (SLSB) 依賴注入雖源自不同陣營,但核心機制高度趨同:**皆採用 Type 2 (Setter 注入) 作為基礎注入模式**。本文通過代碼對比揭示兩者統一本質,並分析對學習路徑的啟示。
@Stateless
public class HelloBean {
private String greeting = "Default Hello";
public void setGreeting(String greeting) { // Setter 注入點
this.greeting = greeting;
}
public String hello() {
return greeting;
}
}
<ejb-jar>
<enterprise-beans>
<session>
<ejb-name>HelloBean</ejb-name>
<ejb-class>com.example.HelloBean</ejb-class>
<session-type>Stateless</session-type>
<env-entry>
<env-entry-name>greeting</env-entry-name>
<env-entry-type>java.lang.String</env-entry-type>
<env-entry-value>Hello, World</env-entry-value>
</env-entry>
</session>
</enterprise-beans>
</ejb-jar>
容器部署時:讀取 env-entry → 實例化 Bean → 呼叫 setGreeting("Hello, World") → Bean 可用。若需求變更,僅修改 XML 值,無需動代碼。
public class HelloService {
private String greeting = "Default Hello";
public void setGreeting(String greeting) {
this.greeting = greeting;
}
public String sayHello() {
return greeting;
}
}
<beans>
<bean id="helloService" class="com.example.HelloService">
<property name="greeting" value="Hello, Spring"/>
</bean>
</beans>
容器啟動時:實例化 Bean → 呼叫 setGreeting("Hello, Spring") → Bean 就緒。
| 維度 | EJB 3 SLSB | Spring IOC | 共同點 |
|---|---|---|---|
| 注入模式 | Setter 注入 (Type 2) | Setter 注入 (Type 2) | 完全一致 |
| 配置載體 | ejb-jar.xml / 部署描述符 | applicationContext.xml | 外部化配置,與代碼分離 |
| 容器角色 | EJB 容器 (應用伺服器內建) | Spring 容器 (輕量級獨立/嵌入) | 管理 Bean 生命週期、依賴解析 |
| Bean 識別 | JNDI 名稱 / @EJB 注入 | Bean ID / @Autowired | 邏輯名稱定位實例 |
| 攔截/增強 | Interceptor / @AroundInvoke | AOP / @Aspect | 橫切關注點分離 |
| 事務管理 | CMT/BMT (@TransactionAttribute) | @Transactional / TransactionTemplate | 聲明式事務 |
Spring 同時支援 Type 2、Type 3;EJB 3 標準化 Type 2 (亦支援建構子注入)。
Spring IOC 與 EJB 3 SLSB 依賴注入,**本質上都是 Type 2 Setter 注入的具體實現**。理解這一統一本質,能讓開發者在兩大陣營間自由切換,專注於業務架構設計而非框架語法差異。學好 Spring,EJB 3/Jakarta EE DI 自然迎刃而解;反之亦然。