Ich bevorzuge einen dritten Ansatz, der das Beste aus
Ansatz 1 und Ansatz 2 herausholt, die von user1016403 beschrieben werden .
Ansatz 3
- Speichern Sie die Datenbankeigenschaften auf dem
server.xml
- Verweisen Sie auf die
server.xml
Datenbankeigenschaften der WebanwendungMETA-INF/context.xml
Ansatz 3 Vorteile
Während der erste Punkt aus Sicherheitsgründen nützlich ist, ist der zweite Punkt nützlich, um auf den Wert der Servereigenschaften aus der Webanwendung zu verweisen, selbst wenn sich die Werte der Servereigenschaften ändern.
Darüber hinaus macht die Entkopplung von Ressourcendefinitionen auf dem Server von ihrer Verwendung durch die Webanwendung eine solche Konfiguration für Organisationen mit unterschiedlicher Komplexität skalierbar, bei denen verschiedene Teams auf verschiedenen Ebenen / Ebenen arbeiten: Das Serveradministratorteam kann ohne Konflikte mit dem Entwicklerteam arbeiten, wenn der Administrator dieselbe teilt JNDI-Name mit dem Entwickler für jede Ressource.
Implementierung von Ansatz 3
Definieren Sie den JNDI-Namen jdbc/ApplicationContext_DatabaseName
.
Deklarieren Sie die jdbc/ApplicationContext_DatabaseName
verschiedenen Eigenschaften und Werte von in Tomcat server.xml
wie folgt:
<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/>
Verknüpfen Sie die jdbc/ApplicationContext_DatabaseName
Eigenschaften der Webanwendung META-INF/context.xml
mit einem anwendungsprivaten JNDI-Kontext, der java:comp/env/
im name
Attribut angegeben ist:
<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>
Um die JNDI-Ressource zu verwenden, geben Sie den JNDI-Namen jdbc/DatabaseName
im Bereitstellungsdeskriptor der Webanwendung an:
<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>
und im Frühjahrskontext:
<jee:jndi-lookup id="DatabaseNameDataSource"
jndi-name="jdbc/DatabaseName"
expected-type="javax.sql.DataSource" />
Ansatz 3 Nachteile
Wenn der JNDI-Name geändert wird, müssen sowohl der server.xml
als auch der META-INF/context.xml
bearbeitet werden, und eine Bereitstellung wäre erforderlich. Trotzdem ist dieses Szenario selten.
Ansatz 3 Variationen
Viele Datenquellen, die von einer Webanwendung verwendet werden
Fügen Sie einfach Konfigurationen zu Tomcat hinzu server.xml
:
<GlobalNamingResources>
<Resource name="jdbc/ApplicationContext_DatabaseName1" ... />
<Resource name="jdbc/ApplicationContext_DatabaseName2" ... />
...
</GlobalNamingResources/>
Fügen Sie eine Link-Webanwendung META-INF/context.xml
über einen anwendungsprivaten JNDI-Kontext hinzu, der java:comp/env/
im name
Attribut angegeben ist:
<Context path="/ApplicationContext" ... >
<ResourceLink global="jdbc/ApplicationContext_DatabaseName1" name="jdbc/DatabaseName1" ... />
<ResourceLink global="jdbc/ApplicationContext_DatabaseName2" name="jdbc/DatabaseName2" ... />
...
</Context>
Fügen Sie abschließend die Verwendung der JNDI-Ressourcen im Bereitstellungsdeskriptor der Webanwendung hinzu:
<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>
...
und im Frühjahrskontext:
<jee:jndi-lookup id="DatabaseName1DataSource"
jndi-name="jdbc/DatabaseName1" ... />
<jee:jndi-lookup id="DatabaseName2DataSource"
jndi-name="jdbc/DatabaseName2" ... />
...
Viele Datenquellen, die von vielen Webanwendungen auf demselben Server verwendet werden
Fügen Sie einfach die Konfiguration zu Tomcat hinzu server.xml
:
<GlobalNamingResources>
<Resource name="jdbc/ApplicationContextX_DatabaseName1" ... />
<Resource name="jdbc/ApplicationContextX_DatabaseName2" ... />
<Resource name="jdbc/ApplicationContextY_DatabaseName1" ... />
<Resource name="jdbc/ApplicationContextY_DatabaseName2" ... />
...
</GlobalNamingResources/>
Die andere Konfiguration sollte aus dem vorherigen Variationsfall ableitbar sein.
Viele Datenquellen in derselben Datenbank, die von vielen Webanwendungen auf demselben Server verwendet werden
In diesem Fall sind die server.xml
Konfigurationen eines Tomcat wie folgt :
<GlobalNamingResources>
<Resource name="jdbc/ApplicationContextX_DatabaseName" ... />
<Resource name="jdbc/ApplicationContextY_DatabaseName" ... />
endet in zwei verschiedenen Webanwendungen META-INF/context.xml
wie:
<Context path="/ApplicationContextX" ... >
<ResourceLink global="jdbc/ApplicationContextX_DatabaseName" name="jdbc/DatabaseName" ... />
</Context>
und wie:
<Context path="/ApplicationContextY" ... >
<ResourceLink global="jdbc/ApplicationContextY_DatabaseName" name="jdbc/DatabaseName" ... />
</Context>
so jemand über die Tatsache besorgt sein könnte , dass die gleichen name="jdbc/DatabaseName"
nachgeschlagen wird, und dann dazu verwendet, die von zwei verschiedenen auf dem gleichen Server bereitgestellten Anwendungen: Das ist kein Problem , weil die jdbc/DatabaseName
ein anwendungs private JNDI Kontext ist java:comp/env/
, so ApplicationContextX
durch die Verwendungjava:comp/env/
nicht kann (beabsichtigt) Suchen Sie nach der verknüpften Ressource global="jdbc/ApplicationContextY_DatabaseName"
.
Wenn Sie sich ohne diese Sorge entspannter fühlen, können Sie natürlich eine andere Namensstrategie verwenden wie:
<Context path="/ApplicationContextX" ... >
<ResourceLink global="jdbc/ApplicationContextX_DatabaseName" name="jdbc/applicationXprivateDatabaseName" ... />
</Context>
und wie:
<Context path="/ApplicationContextY" ... >
<ResourceLink global="jdbc/ApplicationContextY_DatabaseName" name="jdbc/applicationYprivateDatabaseName" ... />
</Context>
<Resource name="jdbc/ApplicationContextX_DatabaseName" ... /> <Resource name="jdbc/ApplicationContextY_DatabaseName" ... />
Wenn die Ressourcen Verbindungspools wären, würden Sie dann zwei separate Pools erhalten, einen pro Webanwendung? Wenn ich von beiden Webanwendungen auf eine Ressource verlinken würde, gäbe es nur einen Verbindungspool, richtig? Gibt es Gründe, das eine dem anderen vorzuziehen? (separate DB-Verbindungspools, einer pro Webanwendung und ein Verbindungspool, der von allen Webanwendungen gemeinsam genutzt wird)? Vielen Dank.