春季如何使用Tomcat提供的JNDI数据源?


159

据说在有关DriverManagerDataSource类的Spring javadoc文章中,该类非常简单,建议使用

使用容器提供的JNDI数据源。这样DataSource可以通过DataSourceSpring ApplicationContext中的bean 形式公开。JndiObjectFactoryBean

问题是:我该如何完成?

例如,如果我希望让DataSourcebean访问我的自定义MySQL数据库,那我需要什么?我应该在上下文配置等中写些什么?

Answers:


302

如果使用基于Spring XML架构的配置,请在Spring上下文中进行如下设置:

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

或者,使用以下简单的bean配置进行设置:

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

您可以使用以下类似方法在tomcat的server.xml中声明JNDI资源:

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

并从Tomcat的web context.xml中引用JNDI资源,如下所示:

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

参考文档:

编辑:此答案已针对Tomcat 8和Spring 4进行了更新。对于Tomcat的默认数据源资源池设置,有一些属性名称更改。


@skaffman是的,但是您提供了到Spring参考文档的链接。
Etienne Miret 2013年

您所说的“ Tomcat的web context.xml”到底是什么文件?
Pavel Niedoba

1
@PavelNiedoba Tomcat将“上下文”用于特定于Tomcat的Web应用程序配置。上下文文件和/或上下文配置可以放置在各个位置,因此我不能给您确切的答案。常见位置是“ /META-INF/context.xml”。请参阅此处的“定义上下文”部分:tomcat.apache.org/tomcat-8.0-doc/config/…– kaliatech 2015
6

嗯...似乎不适用于我的oracle数据库,与postgresql有什么区别吗?
Phate 2015年

1
@Phate在JDBC / JNDI / Tomcat级别上,Oracle与PostgreSQL之间没有根本区别。但是,在Oracle客户端/服务器设置细节方面,Oracle与PostgreSQL有很大不同。原始问题/答案的范围之外。建议发布一个新问题,其中包含您尝试过的内容,特定版本以及所有错误消息的详细信息。例如:stackoverflow.com/questions/10388137/…–
kaliatech

51

使用Spring的JavaConfig机制,您可以这样做:

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

}

2
或者使用更专业的JndiDataSourceLookup
Arend诉Reinersdorff

21

假设您在tomcat配置中有一个“ sampleDS”数据源定义,则可以在其中添加以下几行以applicationContext.xml使用JNDI访问数据源。

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

您必须使用以下命令定义jee前缀的名称空间和架构位置:

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

文档:C.2.3.1 <jee:jndi-lookup/>(简单)

例:

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

您只需要找出应用服务器将数据源绑定到的JNDI名称即可。这完全是特定于服务器的,请查阅服务器上的文档以了解操作方法。

请记住jee,如C.2.3 jee模式中所述,在bean文件的顶部声明名称空间。


8

另一个功能:代替server.xml,可以在
your_application / META-INF / Context.xml中添加“ Resource”标签(根据tomcat docs),如下所示:

<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

根据 Apache Tomcat 7 JNDI数据源HOW-TO页面,必须在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>

这对我行得通


4

在您的春季课程中,您可以注入一个注解如下的bean:

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

然后将其添加到context.xml中

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

您可以使用以下命令在tomcat的server.xml中声明JNDI资源:

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

回到context.xml de spring将此添加

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

如果像这个示例那样注入数据库连接,请确保tomcat lib目录中存在MySQL jar,否则tomcat将无法创建MySQL数据库连接池。


1

我发现此解决方案非常干净,可以完全删除xml配置。

请使用JNDI和spring框架检查此数据库配置。 http://www.unotions.com/design/how-to-create-oracleothersql-db-configuration-using-spring-and-maven/

在本文中,它说明了基于数据库jndi(db / test)配置创建数据库配置多么容易。完成配置后,便会使用此jndi加载所有数据库存储库。我发现有用。如果@Pierre对此有疑问,请告诉我。这是编写数据库配置的完整解决方案。


通过本文,它解释了如何基于数据库jndi(db / test)配置创建数据库配置是多么容易。完成配置后,便会使用此jndi加载所有数据库存储库。我发现有用。如果@Pierre对此有疑问,请告诉我。这是编写数据库配置的完整解决方案。
user3892286 '17

通过本文,它解释了如何基于数据库jndi(db / test)配置创建数据库配置是多么容易。完成配置后,便会使用此jndi加载所有数据库存储库。我发现有用。如果@Pierre对此有疑问,请告诉我。这是编写数据库配置的完整解决方案。
Sergio A.
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.