Comment utiliser JNDI DataSource fourni par Tomcat au printemps?

159

On dit que dans l'article javadoc Spring sur la DriverManagerDataSourceclasse, cette classe est très simple et qu'elle est recommandée

pour utiliser une source de données JNDI fournie par le conteneur. Un tel DataSourcepeut être exposé comme un DataSourcebean dans un Spring ApplicationContext viaJndiObjectFactoryBean

La question est: comment puis-je y parvenir?

Par exemple, si je souhaite avoir un DataSourcebean pour accéder à ma base de données MySQL personnalisée, de quoi aurais-je alors besoin? Que dois-je écrire dans la configuration du contexte, etc.?

Suzan Cioc
la source

Réponses:

302

Si vous utilisez la configuration basée sur le schéma XML de Spring, configurez-la dans le contexte Spring comme suit:

<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:jee="http://www.springframework.org/schema/jee" xsi:schemaLocation="
    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee.xsd">
...
<jee:jndi-lookup id="dbDataSource"
   jndi-name="jdbc/DatabaseName"
   expected-type="javax.sql.DataSource" />

Vous pouvez également configurer en utilisant une configuration de bean simple comme ceci:

<bean id="DatabaseName" class="org.springframework.jndi.JndiObjectFactoryBean">
    <property name="jndiName" value="java:comp/env/jdbc/DatabaseName"/>
</bean>

Vous pouvez déclarer la ressource JNDI dans le fichier server.xml de tomcat en utilisant quelque chose comme ceci:

<GlobalNamingResources>
    <Resource name="jdbc/DatabaseName"
              auth="Container"
              type="javax.sql.DataSource"
              username="dbUser"
              password="dbPassword"
              url="jdbc:postgresql://localhost/dbname"
              driverClassName="org.postgresql.Driver"
              initialSize="20"
              maxWaitMillis="15000"
              maxTotal="75"
              maxIdle="20"
              maxAge="7200000"
              testOnBorrow="true"
              validationQuery="select 1"
              />
</GlobalNamingResources>

Et référencez la ressource JNDI du web context.xml de Tomcat comme ceci:

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

Documentation de référence:

Edit: Cette réponse a été mise à jour pour Tomcat 8 et Spring 4. Il y a eu quelques changements de nom de propriété pour la configuration du pool de ressources de sources de données par défaut de Tomcat .

Kaliatech
la source
@skaffman Oui, mais vous fournissez un lien vers la documentation de référence de Spring.
Etienne Miret
quel fichier voulez-vous dire exactement par "Tomcat's web context.xml"?
Pavel Niedoba
1
@PavelNiedoba Tomcat utilise un «contexte» pour la configuration de l'application Web spécifique à Tomcat. Le fichier de contexte et / ou la configuration de contexte peuvent être placés à différents endroits, je ne peux donc pas vous donner de réponse définitive. Un emplacement courant est "/META-INF/context.xml". Voir la section «Définition d'un contexte» ici: tomcat.apache.org/tomcat-8.0-doc/config/…
kaliatech
Mmm ... ne semble pas fonctionner pour mon oracle db, des différences avec postgresql?
Phate
1
@Phate Il n'y a pas de différences fondamentales entre Oracle et PostgreSQL au niveau JDBC / JNDI / Tomcat. Cependant, Oracle est très différent de PostgreSQL en ce qui concerne les détails de configuration du client / serveur Oracle. En dehors de la portée de la question / réponse originale. Suggérer de publier une nouvelle question avec des détails sur ce que vous avez essayé, des versions spécifiques et des messages d'erreur. Exemple: stackoverflow.com/questions/10388137/…
kaliatech
52

Avec le mécanisme JavaConfig de Spring, vous pouvez le faire comme ceci:

@Configuration
public class MainConfig {

    ...

    @Bean
    DataSource dataSource() {
        DataSource dataSource = null;
        JndiTemplate jndi = new JndiTemplate();
        try {
            dataSource = jndi.lookup("java:comp/env/jdbc/yourname", DataSource.class);
        } catch (NamingException e) {
            logger.error("NamingException for java:comp/env/jdbc/yourname", e);
        }
        return dataSource;
    }

}
Abdull
la source
2
Ou utilisez le JndiDataSourceLookup
Arend v. Reinersdorff
21

En supposant que vous ayez une définition de source de données "sampleDS" dans votre configuration tomcat, vous pouvez ajouter les lignes suivantes à votre applicationContext.xmlpour accéder à la source de données à l'aide de JNDI.

<jee:jndi-lookup expected-type="javax.sql.DataSource" id="springBeanIdForSampleDS" jndi-name="sampleDS"/>

Vous devez définir l'espace de noms et l'emplacement du schéma pour le jeepréfixe en utilisant:

xmlns:jee="http://www.springframework.org/schema/jee"
xsi:schemaLocation="http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd"
Melihcelik
la source
15

Documentation: C.2.3.1 <jee:jndi-lookup/>(simple)

Exemple:

<jee:jndi-lookup id="dataSource" jndi-name="jdbc/MyDataSource"/>

Il vous suffit de savoir à quel nom JNDI votre serveur d'applications a lié la source de données. Ceci est entièrement spécifique au serveur, consultez la documentation sur votre serveur pour savoir comment.

N'oubliez pas de déclarer l' jeeespace de noms en haut de votre fichier beans, comme décrit dans C.2.3 Le schéma jee .

skaffman
la source
8

Autre fonctionnalité: au lieu de server.xml, vous pouvez ajouter la balise "Resource" dans
votre_application / META-INF / Context.xml (selon la documentation de tomcat ) comme ceci:

<Context>
<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"/>
</Context>
Evgen
la source
5

Selon la page HOW-TO Apache Tomcat 7 JNDI Datasource, il doit y avoir une configuration de ressource dans web.xml:

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

Ça marche pour moi

Antonio
la source
4

Dans votre classe de printemps, vous pouvez injecter un haricot annoté comme

@Autowired
@Qualifier("dbDataSource")
private DataSource dataSource;

et vous ajoutez ceci dans votre context.xml

<beans:bean id="dbDataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
    <beans:property name="jndiName" value="java:comp/env/jdbc/MyLocalDB"/>
</beans:bean>

Vous pouvez déclarer la ressource JNDI dans le fichier server.xml de tomcat en utilisant

<Resource name="jdbc/TestDB" 
  global="jdbc/TestDB" 
  auth="Container" 
  type="javax.sql.DataSource" 
  driverClassName="com.mysql.jdbc.Driver" 
  url="jdbc:mysql://localhost:3306/TestDB" 
  username="pankaj" 
  password="pankaj123" 

  maxActive="100" 
  maxIdle="20" 
  minIdle="5" 
  maxWait="10000"/>

retour à context.xml de spring ajouter ceci

<ResourceLink name="jdbc/MyLocalDB"
                global="jdbc/TestDB"
                auth="Container"
                type="javax.sql.DataSource" />

si, comme cet exemple, vous injectez une connexion à la base de données, assurez-vous que le jar MySQL est présent dans le répertoire lib de tomcat, sinon tomcat ne pourra pas créer le pool de connexion de la base de données MySQL.

Toumi
la source
1

J'ai trouvé cette solution très utile d'une manière propre pour supprimer entièrement la configuration xml.

Veuillez vérifier cette configuration de base de données en utilisant JNDI et Spring Framework. http://www.unotions.com/design/how-to-create-oracleothersql-db-configuration-using-spring-and-maven/

Dans cet article, il explique comment créer facilement une configuration de base de données basée sur la configuration de la base de données jndi (db / test). une fois que vous avez terminé la configuration, tous les dépôts de base de données sont chargés à l'aide de ce jndi. J'ai trouvé utile. Si @Pierre a un problème avec cela, faites-le moi savoir. C'est une solution complète pour écrire la configuration de la base de données.

user3892286
la source
par cet article, il explique comment créer facilement une configuration de base de données basée sur la configuration de la base de données jndi (db / test). une fois que vous avez terminé la configuration, tous les dépôts de base de données sont chargés à l'aide de ce jndi. J'ai trouvé utile. Si @Pierre a un problème avec cela, faites-le moi savoir. C'est une solution complète pour écrire la configuration de la base de données.
user3892286
par cet article, il explique comment créer facilement une configuration de base de données basée sur la configuration de la base de données jndi (db / test). une fois que vous avez terminé la configuration, tous les dépôts de base de données sont chargés à l'aide de ce jndi. J'ai trouvé utile. Si @Pierre a un problème avec cela, faites-le moi savoir. C'est une solution complète pour écrire la configuration de la base de données.
Sergio A.