Java EE 6 (JSR 316) 前,數據源定義深度綁定應用服務器:WebLogic 用 `config.xml`、JBoss 用 `-ds.xml`、GlassFish 用 `sun-resources.xml`、Tomcat 用 `context.xml` — **遷移即重寫配置**。Java EE 6 引入標準化註解 `@DataSourceDefinition` / `@DataSourceDefinitions` 並擴展 `web.xml`/`ejb-jar.xml`/`application.xml` `
可標註於:**Servlet、EJB、ServletContextListener、WebService Endpoint、Application-scoped CDI Bean** 等組件類上。
@DataSourceDefinition(
name = "java:app/env/MyAppDataSource", // JNDI 名稱 (必須)
className = "org.postgresql.ds.PGSimpleDataSource", // 驅動 DataSource 實現類
user = "app_user",
password = "s3cr3t",
databaseName = "myapp",
serverName = "db.internal",
portNumber = 5432,
minPoolSize = 5,
maxPoolSize = 20,
properties = { "ssl=true", "connectTimeout=5000" }, // 驅動特定屬性
description = "核心業務數據源",
isolationLevel = Connection.TRANSACTION_READ_COMMITTED,
transactional = true
)
@Stateless
public class OrderService { ... }
@DataSourceDefinitions({
@DataSourceDefinition(name = "java:app/env/PrimaryDS", ...),
@DataSourceDefinition(name = "java:comp/env/LocalDS", ...)
})
@Singleton
@Startup
public class AppInitializer { ... }
| 屬性 | 類型 | 必填 | 默認值 | 說明 |
|---|---|---|---|---|
| name | String | 是 | — | JNDI 名稱,必須以 `java:/`、`java:comp/`、`java:module/`、`java:app/`、`java:global/` 開頭 |
| className | String | 是 | — | JDBC DataSource 實現類 (非 Driver 類),如 `org.postgresql.ds.PGSimpleDataSource` |
| user / password | String | 否 | "" | 認證憑證 |
| databaseName | String | 否 | "" | 數據庫實例名 |
| serverName / portNumber | String / int | 否 | localhost / -1 | 服務器地址端口 |
| minPoolSize / maxPoolSize | int | 否 | 0 / -1 | 連接池範圍 (-1 表無上限) |
| properties | String[] | 否 | {} | 驅動特定屬性 `key=value` 陣列 |
| isolationLevel | int | 否 | READ_COMMITTED | 事務隔離級別 (Connection 常量) |
| transactional | boolean | 否 | true | 是否參與 JTA 事務 |
| description | String | 否 | "" | 管理主控台顯示用 |
Java EE 6 引入**應用組件命名空間**,決定數據源可被哪些組件查找:
| 前綴 | 作用域 | 可見性範圍 | 典型用途 |
|---|---|---|---|
| `java:comp/env/` | 組件環境 | 同一容器內同一組件 (如同一 Servlet、同一 EJB) | 私有資源、測試替身 |
| `java:module/env/` | 模塊環境 | 同一模塊內所有組件 (同一 `ejb-jar.jar`、同一 `web.war`) | 模塊級共享 (如 EJB 共享) |
| `java:app/env/` | 應用環境 | 同一應用 (EAR) 內所有模塊組件 (Web + EJB + Client) | 應用級共享數據源 (最常用) |
| `java:global/env/` | 全局環境 | 同一應用服務器實例內**所有應用** | 跨應用共享 (謹慎使用) |
最佳實踐:內部數據源用 `java:app/env/`;需跨 WAR/EJB 模塊共享時用 `java:app/env/`;極少數跨應用共享才用 `java:global/`。
適用於 `web.xml`、`ejb-jar.xml`、`application.xml`、`application-client.xml`。語法統一:
<data-source>
<name>java:app/env/ApplicationLevelDS</name>
<class-name>org.apache.derby.jdbc.ClientXADataSource</class-name>
<server-name>localhost</server-name>
<port-number>1527</port-number>
<database-name>testdb</database-name>
<user>APP</user>
<password>APP</password>
<property>
<name>connectionAttributes</name>
<value>;create=true</value>
</property>
<!-- 可選屬性 -->
<min-pool-size>5</min-pool-size>
<max-pool-size>20</max-pool-size>
<transactional>true</transactional>
<isolation-level>TRANSACTION_READ_COMMITTED</isolation-level>
</data-source>
若同一應用中,**同名 JNDI** 同時由註解和部署描述符定義 → **部署描述符生效**,註解被忽略。
這符合 Java EE 「部署時覆蓋開發時」的約定,允許運維在不修改代碼的情況下調整數據源參數 (密碼、URL、池大小)。
Java EE 6 的標準化數據源定義 (`@DataSourceDefinition` + `