Ответ 1
Я предпочитаю третий подход, который лучше всего подходит для Подход 1 и Подход 2 описанный user1016403.
Подход 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 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 Datasource</description>
<res-ref-name>jdbc/DatabaseName1</res-ref-name> ...
</resource-ref>
<resource-ref>
<description>DatabaseName2 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/>
остальные конфигурации должны быть выведены из предыдущего варианта вариации.
Многие источники данных в одной базе данных, используемые многими веб-приложениями на одном сервере
В этом случае конфигурации Tomcat server.xml
типа:
<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>