Como usar o JNDI DataSource fornecido pelo Tomcat no Spring?


159

Diz-se que no artigo do Spring javadoc sobre DriverManagerDataSourceclasse, essa classe é muito simples e é recomendada

para usar um JNDI DataSource fornecido pelo contêiner. Tal DataSourcepode ser exposto como um DataSourcebean em um Spring ApplicationContext viaJndiObjectFactoryBean

A questão é: como faço para fazer isso?

Por exemplo, se eu quiser ter um DataSourcebean para acessar meu banco de dados MySQL personalizado, o que eu precisaria então? O que devo escrever na configuração de contexto, etc?

Respostas:


302

Se estiver usando a configuração baseada em esquema XML do Spring, configure no contexto do Spring assim:

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

Como alternativa, configure usando uma configuração de bean simples como esta:

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

Você pode declarar o recurso JNDI no server.xml do tomcat usando algo como isto:

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

E referencie o recurso JNDI no web context.xml do Tomcat da seguinte maneira:

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

Documentação de referência:

Editar: esta resposta foi atualizada para o Tomcat 8 e o Spring 4. Houve algumas alterações no nome da propriedade para a configuração do pool de recursos de fonte de dados padrão do Tomcat .


@skaffman Sim, mas você fornece um link para a documentação de referência do Spring.
Etienne Miret

que arquivo exatamente você quer dizer com "web context.xml do Tomcat"?
Pavel Niedoba

1
@PavelNiedoba O Tomcat usa um "contexto" para a configuração específica do aplicativo da web do tomcat. O arquivo de contexto e / ou a configuração de contexto podem ser colocados em vários locais, por isso não posso fornecer uma resposta definitiva. Um local comum é "/META-INF/context.xml". Consulte a seção "Definindo um contexto" aqui: tomcat.apache.org/tomcat-8.0-doc/config/…
kaliatech 16/15/15

Mmm ... não parece funcionar para o meu oracle db, existem diferenças com o postgresql?
Phate

1
@Phate Não há diferenças fundamentais entre Oracle e PostgreSQL no nível JDBC / JNDI / Tomcat. No entanto, o Oracle é muito diferente do PostgreSQL quando se trata de detalhes de configuração do cliente / servidor Oracle. Escopo externo da pergunta / resposta original. Sugira postar uma nova pergunta com detalhes do que você tentou, versões específicas e quaisquer mensagens de erro. Exemplo: stackoverflow.com/questions/10388137/…
kaliatech

52

Com o mecanismo JavaConfig do Spring, você pode fazer o seguinte:

@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;
    }

}


21

Supondo que você tenha uma definição de fonte de dados "sampleDS" dentro da configuração do tomcat, você pode adicionar as seguintes linhas ao seu applicationContext.xmlpara acessar a fonte de dados usando JNDI.

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

Você deve definir o espaço para nome e o local do esquema para o jeeprefixo usando:

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"

15

Documentação: C.2.3.1 <jee:jndi-lookup/>(simples)

Exemplo:

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

Você só precisa descobrir a que nome JNDI o seu appserver ligou a fonte de dados. Isso é totalmente específico do servidor, consulte os documentos em seu servidor para descobrir como.

Lembre-se de declarar o jeeespaço para nome na parte superior do seu arquivo beans, conforme descrito em C.2.3 O esquema jee .


8

Outro recurso: em vez de server.xml, você pode adicionar a tag "Resource" em
your_application / META-INF / Context.xml (de acordo com os documentos do tomcat ), como este:

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

5

De acordo com a página de instruções do Apache Tomcat 7 JNDI Datasource , deve haver uma configuração de recurso no 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>

Isso funciona para mim


4

Na sua aula de primavera, você pode injetar um feijão anotado como

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

e você adiciona isso no seu context.xml

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

Você pode declarar o recurso JNDI no server.xml do tomcat usando

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

voltar a context.xml de spring adicione isso

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

se, como este exemplo, você estiver injetando conexão com o banco de dados, verifique se o jar do MySQL está presente no diretório lib do tomcat, caso contrário, o tomcat não poderá criar o pool de conexões do banco de dados MySQL.


1

Achei esta solução muito útil de uma maneira limpa para remover completamente a configuração xml.

Por favor, verifique esta configuração de banco de dados usando JNDI e framework Spring. http://www.unotions.com/design/how-to-create-oracleothersql-db-configuration-using-spring-and-maven/

Neste artigo, ele explica como é fácil criar uma configuração de banco de dados com base na configuração do banco de dados jndi (db / test). Depois de concluir a configuração, todos os repositórios db serão carregados usando este jndi. Eu achei útil. Se o @Pierre tiver problemas com isso, entre em contato. É uma solução completa para escrever a configuração de banco de dados.


neste artigo, ele explica como é fácil criar uma configuração de banco de dados com base na configuração do banco de dados jndi (db / test). Depois de concluir a configuração, todos os repositórios db serão carregados usando este jndi. Eu achei útil. Se a @Pierre tiver problemas com isso, entre em contato. É uma solução completa para escrever a configuração de banco de dados.
user3892286

neste artigo, ele explica como é fácil criar uma configuração de banco de dados com base na configuração do banco de dados jndi (db / test). Depois de concluir a configuração, todos os repositórios db serão carregados usando este jndi. Eu achei útil. Se a @Pierre tiver problemas com isso, entre em contato. É uma solução completa para escrever a configuração de banco de dados.
Sergio A.
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.