Я предпочитаю третий подход, который использует лучшее из
подходов 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" ... />Если бы ресурсы были пулами соединений, это дало бы вам два отдельных пула, по одному на каждое веб-приложение ? В то время как, если бы я связался из обоих веб-приложений с одним ресурсом, был бы только один пул соединений, верно? Есть ли причины предпочесть одно другому? (отдельные пулы соединений с БД по одному для каждого веб-приложения против одного пула соединений, общего для всех веб-приложений)? Благодарю.