name example drivermanagerdatasource java spring datasource jndi

java - example - spring jndi datasource oracle



Debería configurar las propiedades de conexión de la base de datos en server.xml o context.xml (5)

Estoy intentando configurar las propiedades de conexión de la base de datos usando JNDI para una aplicación web Spring.

Estoy considerando dos enfoques de la siguiente manera:

Enfoque 1:

En la configuración de Spring, puede tener algo como:

<jee:jndi-lookup id="dataSource" jndi-name="java:comp/env/jdbc/facs"/>

Luego, en su archivo webapp / META-INF/context.xml también debería tener algo similar:

<?xml version=''1.0'' encoding=''utf-8''?> <!-- antiResourceLocking="true" --> <Context path="/podd-apn" reloadable="true" cachingAllowed="false" antiResourceLocking="true" > <Resource name="jdbc/facs" type="javax.sql.DataSource" username="${database.username}" password="${database.password}" driverClassName="org.postgresql.Driver" url="${database.url}" maxActive="8" maxIdle="4" global="jdbc/facs" /> </Context>

Y en su web.xml debe hacer algo como:

<!-- JNDI --> <resource-ref> <description>FACs Datasource</description> <res-ref-name>jdbc/facs</res-ref-name> <res-type>javax.sql.DataSource</res-type> <res-auth>Container</res-auth> </resource-ref>


Enfoque 2:

Configuración en el contexto de primavera de esta manera:

<jee:jndi-lookup id="dbDataSource" jndi-name="jdbc/DatabaseName" expected-type="javax.sql.DataSource" />

Puede declarar el recurso JNDI en server.xml de Tomcat usando algo como esto:

<GlobalNamingResources> <Resource name="jdbc/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/>

Y haga referencia al recurso JNDI desde el contexto web de Tomcat.xml de la siguiente manera:

<ResourceLink name="jdbc/DatabaseName" global="jdbc/DatabaseName" type="javax.sql.DataSource"/>


Mi pregunta es ¿dónde está el mejor lugar para mantener las propiedades de la base de datos? ¿Deberían colocarse en server.xml o context.xml ?

Además, si tengo 2 bases de datos, ¿debería usar dos configuraciones?

Además, ¿es recomendable colocarlos directamente en server.xml o context.xml? ¿O debo configurarlo a través de la consola de la GUI de Tomcat Manager?

¡Gracias!


Prefiero el Método 2 (poner todo (no solo algún atributo en la configuración),

pero en lugar de colocarlos en el server.xml o global context.xml , debe colocarlo en el context.xml.default específico de la aplicación.xml.default YOUR_APP.xml en su tomcat.

El archivo YOUR_APP.xml se encuentra en $catalinaHome/conf/<engine>/<host> (por ejemplo conf / Catalina / localhost / YOUR_APP.xml).

La configuración específica de la aplicación YOUR_APP.xml solo está disponible para la aplicación específica.


Prefiero un tercer enfoque que tome lo mejor del Método 1 y el Método 2 descritos por el usuario1016403 .

Enfoque 3

  1. Guarde las propiedades de la base de datos en el server.xml
  2. server.xml referencia a las propiedades de la base de datos server.xml desde la aplicación web META-INF/context.xml

Enfoque 3 beneficios

Si bien el primer punto es útil por razones de seguridad, el segundo punto es útil para hacer referencia al valor de las propiedades del servidor desde la aplicación web, incluso si los valores de las propiedades del servidor cambian.

Además, al desvincular las definiciones de recursos en el servidor de su uso por la aplicación web, dicha configuración puede escalarse en organizaciones con diversas complejidades donde diferentes equipos trabajan en diferentes niveles / capas: el equipo de administradores del servidor puede trabajar sin conflicto con el equipo de desarrolladores si el administrador comparte el mismo Nombre JNDI con el desarrollador de cada recurso.

Enfoque 3 implementación

Defina el nombre JNDI jdbc/ApplicationContext_DatabaseName .

Declare las propiedades y valores de jdbc/ApplicationContext_DatabaseName en Tomcat''s server.xml usando algo como esto:

<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/>

Enlace las propiedades de jdbc/ApplicationContext_DatabaseName de la aplicación web META-INF/context.xml mediante un contexto JNDI de aplicación privada java:comp/env/ specified en el atributo 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>

Finalmente, para usar el recurso JNDI, especifique el nombre JNDI jdbc/DatabaseName en el descriptor de implementación de la aplicación web:

<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>

y en el contexto de primavera:

<jee:jndi-lookup id="DatabaseNameDataSource" jndi-name="jdbc/DatabaseName" expected-type="javax.sql.DataSource" />

Enfoque 3 inconvenientes

Si el nombre JNDI se cambia, tanto el server.xml como el META-INF/context.xml tendrán que ser editados y será necesario implementarlo; sin embargo, este escenario es raro.

Enfoque 3 variaciones

Muchas fuentes de datos utilizadas por una aplicación web

Simplemente agregue configuraciones al server.xml de Tomcat:

<GlobalNamingResources> <Resource name="jdbc/ApplicationContext_DatabaseName1" ... /> <Resource name="jdbc/ApplicationContext_DatabaseName2" ... /> ... </GlobalNamingResources/>

Agregue la aplicación web de enlace META-INF/context.xml mediante un contexto JNDI de aplicación privada java:comp/env/ specified en el atributo de name :

<Context path="/ApplicationContext" ... > <ResourceLink global="jdbc/ApplicationContext_DatabaseName1" name="jdbc/DatabaseName1" ... /> <ResourceLink global="jdbc/ApplicationContext_DatabaseName2" name="jdbc/DatabaseName2" ... /> ... </Context>

Finalmente, agregue el uso de recursos JNDI en el descriptor de implementación de la aplicación web:

<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> ...

y en el contexto de primavera:

<jee:jndi-lookup id="DatabaseName1DataSource" jndi-name="jdbc/DatabaseName1" ... /> <jee:jndi-lookup id="DatabaseName2DataSource" jndi-name="jdbc/DatabaseName2" ... /> ...


Muchas fuentes de datos utilizadas por muchas aplicaciones web en el mismo servidor

Simplemente agregue la configuración al server.xml de Tomcat:

<GlobalNamingResources> <Resource name="jdbc/ApplicationContextX_DatabaseName1" ... /> <Resource name="jdbc/ApplicationContextX_DatabaseName2" ... /> <Resource name="jdbc/ApplicationContextY_DatabaseName1" ... /> <Resource name="jdbc/ApplicationContextY_DatabaseName2" ... /> ... </GlobalNamingResources/>

la configuración de los demás debe ser deducible del caso de variación anterior.


Muchas fuentes de datos a la misma base de datos utilizada por muchas aplicaciones web en el mismo servidor

En tal caso, las configuraciones server.xml de Tomcat les server.xml :

<GlobalNamingResources> <Resource name="jdbc/ApplicationContextX_DatabaseName" ... /> <Resource name="jdbc/ApplicationContextY_DatabaseName" ... />

termina en dos aplicaciones web diferentes META-INF/context.xml como:

<Context path="/ApplicationContextX" ... > <ResourceLink global="jdbc/ApplicationContextX_DatabaseName" name="jdbc/DatabaseName" ... /> </Context>

y, como:

<Context path="/ApplicationContextY" ... > <ResourceLink global="jdbc/ApplicationContextY_DatabaseName" name="jdbc/DatabaseName" ... /> </Context>

entonces, alguien podría estar preocupado por el hecho de que el mismo name="jdbc/DatabaseName" es buscado, y luego utilizado, por dos aplicaciones diferentes implementadas en el mismo servidor: esto no es un problema porque el jdbc/DatabaseName es una aplicación- contexto JNDI privado java:comp/env/ , entonces ApplicationContextX utilizando java:comp/env/ no puede (por diseño) buscar el recurso vinculado a global="jdbc/ApplicationContextY_DatabaseName" .

Por supuesto, si te sientes más relajado sin esta preocupación, puedes usar una estrategia de nombres diferente como:

<Context path="/ApplicationContextX" ... > <ResourceLink global="jdbc/ApplicationContextX_DatabaseName" name="jdbc/applicationXprivateDatabaseName" ... /> </Context>

y, como:

<Context path="/ApplicationContextY" ... > <ResourceLink global="jdbc/ApplicationContextY_DatabaseName" name="jdbc/applicationYprivateDatabaseName" ... /> </Context>


También puede usar el soporte URL JNDI para diferentes configuraciones de aplicaciones para prueba, prueba de integración, producción.

<Context> ... <Resource auth="Container" factory="com.benasmussen.jndi.url.URLFactory" name="url/MyUrl" type="java.net.URL" url="file:///your/path/to/file"/> ... </Context> <jee:jndi-lookup id="myUrl" jndi-name="java:comp/env/url/MyUrl" expected-type="java.net.URL" />

Consulte el Soporte de JNDI URL del proyecto GitHub para habilitar el soporte de URL JNDI para los servidores Tomcat.


paso 1: context.xml

<Context path="/projectname"> <Resource auth="Container" driverClassName="com.mysql.jdbc.Driver" logAbandoned="true" maxActive="100" `` maxIdle="30" maxWait="10000" name="refname" removeAbandoned="true" removeAbandonedTimeout="60" type="javax.sql.DataSource" url="jdbc:mysql://localhost:8080/dbname" username="root" password="root"/> </Context>

Paso 2: web.xml

<resource-ref> <description>DB Connection</description> <res-ref-name>refname</res-ref-name> <res-type>javax.sql.DataSource</res-type> <res-auth>Container</res-auth> </resource-ref>

Paso 3: crea una clase para obtener conexión

Connection connection = null; Context context = (Context) new InitialContext().lookup("java:comp/env"); DataSource ds = (DataSource) context.lookup("refname"); connection = ds.getConnection();

Todo está listo


Enfoque 4

En lugar de usar JNDI, trabajo con archivos .properties y compilo un objeto complejo durante la inicialización del programa en vez del tiempo de configuración.

Ya usas Spring y es fácil construir DataSource de la siguiente manera:

<context:property-placeholder location="classpath:app.properties"/> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <property name="driverClassName" value="oracle.jdbc.OracleDriver"/> <property name="url" value="jdbc:oracle:thin:@${db.host}:${db.port}:${db.user}"/> <property name="username" value="${db.user}"/> <property name="password" value="${db.pass}"/> </bean>

Estoy totalmente de acuerdo con Ralph en el uso del descriptor de implementación en $CATALINA_BASE/conf/[enginename]/[hostname]/$APP.xml pero en su lugar JNDI me gusta el archivo de valor-clave simple.

Con Spring inyectando las propiedades anteriores en los campos de frijol es fácil:

@Value("${db.user}") String defaultSchema;

en lugar de JNDI:

@Inject ApplicationContext context; Enviroment env = context.getEnvironment(); String defaultSchema = env.getProperty("db.user");

Tenga en cuenta también que EL permite esto (valores predeterminados y sustitución recursiva profunda):

@Value(''${db.user:testdb}'') private String dbUserName; <property name=''username'' value=''${db.user.${env}}''/>

Para externalizar el archivo .properties utilizo Tomcat 7 moderno que tiene org.apache.catalina.loader.VirtualWebappLoader :

<Loader className="org.apache.catalina.loader.VirtualWebappLoader" virtualClasspath="/srv/web/app/"/>

Por lo tanto, sus devops llenan virtualClasspath con rutas completas externas locales separadas por aplicación y ponen app.properties locales en ese directorio.

Ver también: