【问题标题】:How to use JNDI DataSource provided by Tomcat in Spring?Spring中如何使用Tomcat提供的JNDI DataSource?
【发布时间】:2012-02-29 07:09:05
【问题描述】:

据说在Spring javadoc关于DriverManagerDataSource类的文章中,这个类很简单,值得推荐

使用容器提供的 JNDI 数据源。这样的DataSource 可以通过JndiObjectFactoryBean 暴露为Spring ApplicationContext 中的DataSource bean

问题是:我该如何做到这一点?

例如,如果我想让DataSource bean 访问我的自定义 MySQL 数据库,那么我需要什么?上下文配置等应该写什么?

【问题讨论】:

    标签: java spring tomcat datasource jndi


    【解决方案1】:

    如果使用 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 的 default 数据源资源池设置的属性名称发生了一些变化。

    【讨论】:

    • @skaffman 是的,但是您提供了 Spring 参考文档的链接。
    • “Tomcat 的 web context.xml”到底是什么文件?
    • @PavelNiedoba Tomcat 为 Tomcat 特定的 Web 应用程序配置使用“上下文”。上下文文件和/或上下文配置可以放在不同的位置,所以我不能给你一个明确的答案。一个常见的位置是“/META-INF/context.xml”。请参阅此处的“定义上下文”部分:tomcat.apache.org/tomcat-8.0-doc/config/…
    • 嗯...似乎不适用于我的 oracle 数据库,与 postgresql 有什么不同吗?
    • @Phate 在 JDBC/JNDI/Tomcat 级别上,Oracle 与 PostgreSQL 没有根本区别。但是,在 Oracle 客户端/服务器设置细节方面,Oracle 与 PostgreSQL 有很大不同。原始问题/答案的范围之外。建议发布一个新问题,详细说明您尝试过的内容、特定版本和任何错误消息。示例:stackoverflow.com/questions/10388137/…
    【解决方案2】:

    使用 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;
        }
    
    }
    

    【讨论】:

    【解决方案3】:

    假设您的 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"
    

    【讨论】:

      【解决方案4】:

      文档:C.2.3.1 &lt;jee:jndi-lookup/&gt; (simple)

      例子:

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

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

      记得在 bean 文件的顶部声明 jee 命名空间,如 C.2.3 The jee schema 中所述。

      【讨论】:

        【解决方案5】:

        另一个特点: 代替 server.xml,您可以在
        中添加“资源”标签 your_application/META-INF/Context.xml (据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>
        

        【讨论】:

          【解决方案6】:

          根据Apache Tomcat 7 JNDI Datasource HOW-TO page,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>
          

          这对我有用

          【讨论】:

            【解决方案7】:

            在您的 spring 类中,您可以注入一个注释为

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

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

            【讨论】:

              【解决方案8】:

              我发现这个解决方案非常有助于以一种干净的方式完全删除 xml 配置。

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

              通过这篇文章,它解释了基于数据库 jndi(db/test) 配置创建数据库配置是多么容易。完成配置后,所有数据库存储库都将使用此 jndi 加载。我确实觉得有用。如果@Pierre 对此有疑问,请告诉我。编写db配置的完整解决方案。

              【讨论】:

              • 通过这篇文章,它解释了基于数据库 jndi(db/test) 配置创建数据库配置是多么容易。完成配置后,所有数据库存储库都将使用此 jndi 加载。我确实觉得有用。如果@Pierre 对此有疑问,请告诉我。这是编写数据库配置的完整解决方案。
              • 通过这篇文章,它解释了基于数据库 jndi(db/test) 配置创建数据库配置是多么容易。完成配置后,所有数据库存储库都将使用此 jndi 加载。我确实觉得有用。如果@Pierre 对此有疑问,请告诉我。这是编写数据库配置的完整解决方案。
              猜你喜欢
              • 2015-03-18
              • 2016-05-01
              • 2014-04-24
              • 2015-09-11
              • 1970-01-01
              • 1970-01-01
              • 2014-04-01
              • 2015-12-11
              • 2012-05-28
              相关资源
              最近更新 更多