我更喜欢第三种方法,它从user1016403描述的方法1和方法2中汲取最佳效果。
方法 3
- 将数据库属性保存在
server.xml
- 从 Web 应用程序引用数据库属性
server.xml
META-INF/context.xml
方法 3 的好处
虽然第一点出于安全原因很有用,但第二点对于从 Web 应用程序引用服务器属性值很有用,即使服务器属性值将发生更改也是如此。
此外,将服务器上的资源定义与 Web 应用程序使用它们分离,使得此类配置可以在具有不同复杂性的组织(其中不同团队在不同的层/层上工作)进行扩展:如果管理员与每个资源的开发人员共享相同的 JNDI 名称,则服务器管理员团队可以在不与开发人员团队发生冲突的情况下工作。
方法 3 实现
定义 JNDI 名称 。jdbc/ApplicationContext_DatabaseName
在 Tomcat 中声明 的各种属性和值,如下所示:jdbc/ApplicationContext_DatabaseName
server.xml
<GlobalNamingResources>
<Resource name="jdbc/ApplicationContext_DatabaseName" auth="Container" type="javax.sql.DataSource"
username="dbUsername" password="dbPasswd"
url="jdbc:postgresql://localhost/dbname"
driverClassName="org.postgresql.Driver"
initialSize="5" maxWait="5000"
maxActive="120" maxIdle="5"
validationQuery="select 1"
poolPreparedStatements="true"/>
</GlobalNamingResources/>
通过属性中指定的应用程序私有 JNDI 上下文从 Web 应用程序链接 的属性:jdbc/ApplicationContext_DatabaseName
META-INF/context.xml
java:comp/env/
name
<Context path="/ApplicationContext" ... >
<!--
"global" attribute links to GlobalNamingResources in the ${catalina.base}/conf/server.xml (server administrator team)
"name" attribute is relative to the application-private JNDI context java:comp/env/ and is looked up from the java web application (application developer team)
-->
<ResourceLink global="jdbc/ApplicationContext_DatabaseName" name="jdbc/DatabaseName" type="javax.sql.DataSource"/>
</Context>
最后,为了使用 JNDI 资源,请在 Web 应用程序的部署描述符中指定 JNDI 名称:jdbc/DatabaseName
<resource-ref>
<description>DatabaseName's Datasource</description>
<res-ref-name>jdbc/DatabaseName</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
在春季背景下:
<jee:jndi-lookup id="DatabaseNameDataSource"
jndi-name="jdbc/DatabaseName"
expected-type="javax.sql.DataSource" />
方法3的缺点
如果更改了 JNDI 名称,则必须对 和 进行编辑,并且需要进行部署;然而,这种情况很少见。server.xml
META-INF/context.xml
方法 3 变体
一个 Web 应用程序使用多个数据源
只需将配置添加到Tomcat的:server.xml
<GlobalNamingResources>
<Resource name="jdbc/ApplicationContext_DatabaseName1" ... />
<Resource name="jdbc/ApplicationContext_DatabaseName2" ... />
...
</GlobalNamingResources/>
通过属性中指定的应用程序私有 JNDI 上下文添加链接 Web 应用程序:META-INF/context.xml
java:comp/env/
name
<Context path="/ApplicationContext" ... >
<ResourceLink global="jdbc/ApplicationContext_DatabaseName1" name="jdbc/DatabaseName1" ... />
<ResourceLink global="jdbc/ApplicationContext_DatabaseName2" name="jdbc/DatabaseName2" ... />
...
</Context>
最后,在 Web 应用程序的部署描述符中添加 JNDI 资源使用情况:
<resource-ref>
<description>DatabaseName1's Datasource</description>
<res-ref-name>jdbc/DatabaseName1</res-ref-name> ...
</resource-ref>
<resource-ref>
<description>DatabaseName2's Datasource</description>
<res-ref-name>jdbc/DatabaseName2</res-ref-name> ...
</resource-ref>
...
在春季背景下:
<jee:jndi-lookup id="DatabaseName1DataSource"
jndi-name="jdbc/DatabaseName1" ... />
<jee:jndi-lookup id="DatabaseName2DataSource"
jndi-name="jdbc/DatabaseName2" ... />
...
同一服务器上的许多 Web 应用程序使用的许多数据源
只需将配置添加到Tomcat的:server.xml
<GlobalNamingResources>
<Resource name="jdbc/ApplicationContextX_DatabaseName1" ... />
<Resource name="jdbc/ApplicationContextX_DatabaseName2" ... />
<Resource name="jdbc/ApplicationContextY_DatabaseName1" ... />
<Resource name="jdbc/ApplicationContextY_DatabaseName2" ... />
...
</GlobalNamingResources/>
其他配置应从以前的变体情况中推断出来。
同一服务器上的许多 Web 应用程序使用的同一数据库的多个数据源
在这种情况下,Tomcat的配置如下:server.xml
<GlobalNamingResources>
<Resource name="jdbc/ApplicationContextX_DatabaseName" ... />
<Resource name="jdbc/ApplicationContextY_DatabaseName" ... />
最终在两个不同的Web应用程序中,例如:META-INF/context.xml
<Context path="/ApplicationContextX" ... >
<ResourceLink global="jdbc/ApplicationContextX_DatabaseName" name="jdbc/DatabaseName" ... />
</Context>
和喜欢:
<Context path="/ApplicationContextY" ... >
<ResourceLink global="jdbc/ApplicationContextY_DatabaseName" name="jdbc/DatabaseName" ... />
</Context>
因此,有人可能会担心部署在同一服务器上的两个不同的应用程序查找并随后使用相同的应用程序:这不是问题,因为它是应用程序私有JNDI上下文,因此通过使用java:comp/env/
无法(通过设计)查找链接到的资源。name="jdbc/DatabaseName"
jdbc/DatabaseName
java:comp/env/
ApplicationContextX
global="jdbc/ApplicationContextY_DatabaseName"
当然,如果您感到更放松而不必担心,则可以使用不同的命名策略,例如:
<Context path="/ApplicationContextX" ... >
<ResourceLink global="jdbc/ApplicationContextX_DatabaseName" name="jdbc/applicationXprivateDatabaseName" ... />
</Context>
和喜欢:
<Context path="/ApplicationContextY" ... >
<ResourceLink global="jdbc/ApplicationContextY_DatabaseName" name="jdbc/applicationYprivateDatabaseName" ... />
</Context>