Я предпочитаю третий подход, который использует лучшее из
подходов 1 и 2, описанных пользователем 1016403 .
Подход 3
- Сохраните свойства базы данных на
server.xml
- ссылаться на
server.xml
свойства базы данных из веб-приложенияMETA-INF/context.xml
Подход 3 преимущества
Хотя первый пункт полезен по соображениям безопасности, второй пункт полезен для ссылки на значение свойств сервера из веб-приложения, даже если значения свойств сервера изменятся.
Более того, разделение определений ресурсов на сервере от их использования веб-приложением делает такую конфигурацию масштабируемой в разных организациях с различной сложностью, где разные группы работают на разных уровнях / уровнях: команда администраторов сервера может работать без конфликтов с командой разработчиков, если администратор использует то же самое. Имя JNDI с указанием разработчика для каждого ресурса.
Реализация подхода 3
Определите имя JNDI jdbc/ApplicationContext_DatabaseName
.
Объявите jdbc/ApplicationContext_DatabaseName
различные свойства и значения в Tomcat, 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/>
Свяжите jdbc/ApplicationContext_DatabaseName
свойства из веб-приложения META-INF/context.xml
с помощью частного контекста JNDI приложения, 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, укажите имя 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>
и в контексте Spring:
<jee:jndi-lookup id="DatabaseNameDataSource"
jndi-name="jdbc/DatabaseName"
expected-type="javax.sql.DataSource" />
Подход 3 недостатка
Если имя JNDI получает изменилось , то как server.xml
и META-INF/context.xml
должны быть отредактированы и развертывание будет необходимо; тем не менее такой сценарий встречается редко.
Подход 3 варианта
Множество источников данных, используемых одним веб-приложением
Просто добавьте конфигурации в Tomcat server.xml
:
<GlobalNamingResources>
<Resource name="jdbc/ApplicationContext_DatabaseName1" ... />
<Resource name="jdbc/ApplicationContext_DatabaseName2" ... />
...
</GlobalNamingResources/>
Добавить веб-приложение ссылки META-INF/context.xml
с помощью частного JNDI-контекста приложения, java:comp/env/
указанного в name
атрибуте:
<Context path="/ApplicationContext" ... >
<ResourceLink global="jdbc/ApplicationContext_DatabaseName1" name="jdbc/DatabaseName1" ... />
<ResourceLink global="jdbc/ApplicationContext_DatabaseName2" name="jdbc/DatabaseName2" ... />
...
</Context>
Наконец, добавьте использование ресурсов 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>
...
и в контексте Spring:
<jee:jndi-lookup id="DatabaseName1DataSource"
jndi-name="jdbc/DatabaseName1" ... />
<jee:jndi-lookup id="DatabaseName2DataSource"
jndi-name="jdbc/DatabaseName2" ... />
...
Множество источников данных, используемых многими веб-приложениями на одном сервере
Просто добавьте конфигурацию в 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/>
остальные конфигурации должны быть выведены из предыдущего варианта.
Многие источники данных в одной базе данных используются многими веб-приложениями на одном сервере.
В таком случае server.xml
конфигурации Tomcat, такие как:
<GlobalNamingResources>
<Resource name="jdbc/ApplicationContextX_DatabaseName" ... />
<Resource name="jdbc/ApplicationContextY_DatabaseName" ... />
попадает в два разных веб-приложения, 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>
поэтому кто-то может быть обеспокоен тем фактом, что одно name="jdbc/DatabaseName"
и то же просматривается, а затем используется двумя разными приложениями, развернутыми на одном сервере: это не проблема, потому что jdbc/DatabaseName
это частный контекст JNDI приложения java:comp/env/
, поэтому ApplicationContextX
при использованииjava:comp/env/
невозможно (по дизайну) найдите ресурс, на который есть ссылка 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>
<Resource name="jdbc/ApplicationContextX_DatabaseName" ... /> <Resource name="jdbc/ApplicationContextY_DatabaseName" ... />
Если бы ресурсы были пулами соединений, это дало бы вам два отдельных пула, по одному на каждое веб-приложение ? В то время как, если бы я связался из обоих веб-приложений с одним ресурсом, был бы только один пул соединений, верно? Есть ли причины предпочесть одно другому? (отдельные пулы соединений с БД по одному для каждого веб-приложения против одного пула соединений, общего для всех веб-приложений)? Благодарю.