9

更新:显然 Tomcat,从 7.0.11 开始,为你关闭了 DataSource,所以它在 webapp 的 contextDestroyed 中不可用。请参阅:https ://issues.apache.org/bugzilla/show_bug.cgi?id=25060

你好,

我正在使用 Spring 3.0 和 Java 1.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 侦听器中显式关闭数据源?

谢谢,

保罗

4

3 回答 3

5

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

在 web.xml 里面

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

编码:

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);
  }
}
于 2011-03-24T18:41:56.193 回答
4

不,DataSource这里由远程 JNDI 容器管理,该容器的工作是管理DataSource. Spring 只是利用它,它不管理它。

即使你想,你也做不到——DataSource没有close()方法,或者类似的东西。

于 2011-03-23T16:15:25.117 回答
1

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

于 2011-03-23T16:12:54.063 回答