Spring 我应该关闭JNDI获得的数据源吗?

Spring 我应该关闭JNDI获得的数据源吗?,spring,tomcat7,datasource,jndi,spring-jdbc,Spring,Tomcat7,Datasource,Jndi,Spring Jdbc,更新:显然,Tomcat从7.0.11开始,为您关闭了数据源,因此它在webapp的上下文中不可用。见: 嗨 我正在使用Spring3.0和Java1.6 如果以这种方式获取数据源: <bean id="dataSource" class="my.data.Source" destroy-method="close"> <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>

更新:显然,Tomcat从7.0.11开始,为您关闭了数据源,因此它在webapp的上下文中不可用。见:

我正在使用Spring3.0和Java1.6

如果以这种方式获取数据源:

<bean id="dataSource" class="my.data.Source" destroy-method="close">
    <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>
    <property name="url" value="jdbc:oracle:thin:@localhost:1521:home"/>
    <property name="username" value="user"/>
    <property name="password" value="pw"/>
</bean>

然后,当bean被销毁时,数据源被关闭

如果我得到如下数据源:

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

那么,我是否必须显式关闭contextDestroyed listener中的数据源

谢谢


Paul

当您通过JNDI查找获得数据源时,它将是一个在容器中配置的共享资源。它由容器而不是应用程序管理,因此不需要(没有办法)关闭它

否。此处的
数据源
由远程JNDI容器管理,该容器的工作是管理
数据源
的生命周期。Spring只是利用它,而不是管理它


即使你想,你也不能-
DataSource
没有
close()
方法,或者类似的方法。

我不同意。我将向web.xml添加一个侦听器,并实现contextdestromed()方法。当web应用被销毁或取消部署时,web容器/应用服务器将调用此方法。在contextDestroyed()中,我将关闭数据源

在web.xml内部

<listener>
   <listener-class>util.myApplicationWatcher</listener-class>
</listener>

我将数据源转换为基础类(例如BasicDataSource),并调用该类的close方法。这是一件坏事还是没有必要?我应该做些什么来清理contextDestroyed中的数据访问?结果证明这是正确的答案。我把这个问题贴到Tomcat邮件列表上,其中一位说,因为EE规范说JNDI资源是在查找时创建的(因为,我假设java:comp资源不是在组件之间共享的),所以webapp应该在contextDestroyed中处理它。看起来Tomcat 7将为您处理数据源:
package util;

public class myApplicationWatcher implementes ServletContextListener
{
  public void contextInitialized(ServletContextEvent cs)
  {
      // This web application is getting started

      // Initialize connection pool here by running a query
      JdbcTemplate jt = new JdbcTemplate(Dao.getDataSource() );
      jt.queryForInt("Select count(col1) from some_table");
  }

  public void contextDestroyed(ServeletContextEvent ce)
  {
      // This web application is getting undeployed or destroyed 

      // close the connection pool
      Dao.closeDataSource();
  }
}

public class Dao
{
  private static DataSource ds;
  private static bDataSourceInitialized=false;
  private static void initializeDataSource() throws Exception
  {
    InitialContext initial = new InitialContext();

    ds = (DataSource) initial.lookup(TOMCAT_JNDI_NAME);

    if (ds.getConnection() == null)
    {
      throw new RuntimeException("I failed to find the TOMCAT_JNDI_NAME");
    }

    bDataSourceInitialized=true;
  }

  public static void closeDataSource() throws Exception
  {
    // Cast my DataSource class to a c3po connection pool class
    // since c3po is what I use in my context.xml
    ComboPooledDataSource cs = (ComboPooledDatasource) ds;

    // close this connection pool
    cs.close();
  }

  public static DataSource getDataSource() throws Exception
  {
    if (bDataSourceInitialized==false)
    {
      initializeDataSource();
    }

    return(ds);
  }
}