Wolę trzecie podejście, które czerpie to, co najlepsze z
Podejścia 1 i Podejścia 2 opisanego przez użytkownika1016403 .
Podejście 3
- Zapisz właściwości bazy danych w
server.xml
- odwołać się do
server.xml
właściwości bazy danych z aplikacji internetowejMETA-INF/context.xml
Podejście 3 korzyści
Podczas gdy pierwszy punkt jest przydatny ze względów bezpieczeństwa, drugi punkt jest przydatny do odwoływania się do wartości właściwości serwera z aplikacji internetowej, nawet jeśli wartości właściwości serwera ulegną zmianie.
Ponadto oddzielenie definicji zasobów na serwerze od ich wykorzystania przez aplikację internetową sprawia, że taka konfiguracja jest skalowalna w różnych organizacjach o różnym stopniu złożoności, w których różne zespoły pracują na różnych poziomach / warstwach: zespół administratorów serwera może pracować bez konfliktu z zespołem programistów, jeśli administrator udostępnia to samo Nazwa JNDI z deweloperem dla każdego zasobu.
Podejście 3 wdrożenie
Zdefiniuj nazwę JNDI jdbc/ApplicationContext_DatabaseName
.
Zadeklaruj jdbc/ApplicationContext_DatabaseName
różne właściwości i wartości w Tomcat, server.xml
używając czegoś takiego:
<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/>
Połącz jdbc/ApplicationContext_DatabaseName
właściwości z aplikacji internetowej META-INF/context.xml
za pomocą prywatnego kontekstu JNDI aplikacji java:comp/env/
określonego w name
atrybucie:
<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>
Na koniec, aby użyć zasobu JNDI, określ nazwę JNDI jdbc/DatabaseName
w deskryptorze wdrażania aplikacji WWW:
<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>
aw kontekście wiosny:
<jee:jndi-lookup id="DatabaseNameDataSource"
jndi-name="jdbc/DatabaseName"
expected-type="javax.sql.DataSource" />
Podejmij 3 wady
Jeśli nazwa JNDI zostanie zmieniona wtedy zarówno server.xml
i META-INF/context.xml
będą musiały być edytowane i wdrożyć byłoby konieczne; niemniej jednak ten scenariusz jest rzadki.
Podejdź do 3 odmian
Wiele źródeł danych używanych przez jedną aplikację internetową
Po prostu dodaj konfiguracje do Tomcat server.xml
:
<GlobalNamingResources>
<Resource name="jdbc/ApplicationContext_DatabaseName1" ... />
<Resource name="jdbc/ApplicationContext_DatabaseName2" ... />
...
</GlobalNamingResources/>
Dodaj aplikację internetową odsyłacza META-INF/context.xml
za pomocą prywatnego kontekstu JNDI aplikacji java:comp/env/
określonego w name
atrybucie:
<Context path="/ApplicationContext" ... >
<ResourceLink global="jdbc/ApplicationContext_DatabaseName1" name="jdbc/DatabaseName1" ... />
<ResourceLink global="jdbc/ApplicationContext_DatabaseName2" name="jdbc/DatabaseName2" ... />
...
</Context>
Na koniec dodaj użycie zasobów JNDI w deskryptorze wdrażania aplikacji internetowej:
<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>
...
aw kontekście wiosny:
<jee:jndi-lookup id="DatabaseName1DataSource"
jndi-name="jdbc/DatabaseName1" ... />
<jee:jndi-lookup id="DatabaseName2DataSource"
jndi-name="jdbc/DatabaseName2" ... />
...
Wiele źródeł danych używanych przez wiele aplikacji internetowych na tym samym serwerze
Po prostu dodaj konfigurację do 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/>
inne konfiguracje powinny dać się wyprowadzić z poprzedniego przypadku zmienności.
Wiele źródeł danych do tej samej bazy danych używanej przez wiele aplikacji internetowych na tym samym serwerze
W takim przypadku server.xml
konfiguracje Tomcata, takie jak:
<GlobalNamingResources>
<Resource name="jdbc/ApplicationContextX_DatabaseName" ... />
<Resource name="jdbc/ApplicationContextY_DatabaseName" ... />
kończy się w dwóch różnych aplikacjach internetowych, META-INF/context.xml
takich jak:
<Context path="/ApplicationContextX" ... >
<ResourceLink global="jdbc/ApplicationContextX_DatabaseName" name="jdbc/DatabaseName" ... />
</Context>
i jak:
<Context path="/ApplicationContextY" ... >
<ResourceLink global="jdbc/ApplicationContextY_DatabaseName" name="jdbc/DatabaseName" ... />
</Context>
więc ktoś może się martwić faktem, że to samo name="jdbc/DatabaseName"
jest wyszukiwane, a następnie używane przez dwie różne aplikacje wdrożone na tym samym serwerze: nie stanowi to problemu, ponieważ jdbc/DatabaseName
jest to kontekst JNDI prywatnej aplikacji java:comp/env/
, więc ApplicationContextX
używającjava:comp/env/
nie można (zgodnie z projektem) wyszukuje zasoby, z którymi jest powiązany global="jdbc/ApplicationContextY_DatabaseName"
.
Oczywiście, jeśli czułeś się bardziej zrelaksowany bez tego zmartwienia, możesz użyć innej strategii nazewnictwa, na przykład:
<Context path="/ApplicationContextX" ... >
<ResourceLink global="jdbc/ApplicationContextX_DatabaseName" name="jdbc/applicationXprivateDatabaseName" ... />
</Context>
i jak:
<Context path="/ApplicationContextY" ... >
<ResourceLink global="jdbc/ApplicationContextY_DatabaseName" name="jdbc/applicationYprivateDatabaseName" ... />
</Context>
<Resource name="jdbc/ApplicationContextX_DatabaseName" ... /> <Resource name="jdbc/ApplicationContextY_DatabaseName" ... />
Gdyby zasoby były pulami połączeń, czy dałoby to dwie oddzielne pule, po jednej na aplikację internetową? Zważywszy, że jeśli połączyłem się z obu aplikacji internetowych do jednego zasobu, byłaby tylko jedna pula połączeń, prawda? Jakieś powody, by preferować jeden od drugiego? (oddzielne pule połączeń DB, po jednej na aplikację internetową w porównaniu z jedną pulą połączeń współdzieloną przez wszystkie aplikacje internetowe)? Dzięki.