我有一个Spring Hibernate webapp,其中HikariCP在Jetty上运行,以下文件位于基本webapps文件夹中:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_0.dtd">
<Configure id='testServer' class="org.eclipse.jetty.webapp.WebAppContext">
<Set name="contextPath">/myServer</Set>
<Set name="war">C:\mypath\myServer.war</Set>
<New id="testDataSource" class="org.eclipse.jetty.plus.jndi.Resource">
<Arg><Ref refid="testServer"/></Arg>
<Arg>jdbc/myDB</Arg>
<Arg>
<New class="com.zaxxer.hikari.HikariDataSource">
<Arg>
<New class="com.zaxxer.hikari.HikariConfig">
<Set name="connectionTestQuery">SELECT 1</Set>
<Set name="dataSourceClassName">com.mysql.jdbc.jdbc2.optional.MysqlDataSource</Set>
<Set name="maximumPoolSize">20</Set>
<Set name="connectionTimeout">30000</Set>
<Set name="username">user</Set>
<Set name="password">password</Set>
<Call name="addDataSourceProperty">
<Arg>url</Arg>
<Arg>jdbc:mysql://localhost/mydb?zeroDateTimeBehavior=convertToNull</Arg>
</Call>
<Call name="addDataSourceProperty">
<Arg>user</Arg>
<Arg>user</Arg>
</Call>
<Call name="addDataSourceProperty">
<Arg>password</Arg>
<Arg>password</Arg>
</Call>
<Call name="addDataSourceProperty">
<Arg>cachePrepStmts</Arg>
<Arg>true</Arg>
</Call>
<Call name="addDataSourceProperty">
<Arg>prepStmtCacheSize</Arg>
<Arg>250</Arg>
</Call>
<Call name="addDataSourceProperty">
<Arg>prepStmtCacheSqlLimit</Arg>
<Arg>2048</Arg>
</Call>
<Call name="addDataSourceProperty">
<Arg>useServerPrepStmts</Arg>
<Arg>true</Arg>
</Call>
</New>
</Arg>
</New>
</Arg>
</New>
</Configure>
在我的applicationContext.xml文件中,我能够使用以下内容成功查找和使用数据源:
<jee:jndi-lookup id="dataSource" jndi-name="jdbc/myDB"/>
我遇到的问题是,当我热部署新的war文件时,HikariCP数据源连接池保持打开状态,并且与数据库的连接仍然存在。
我正在尝试使用类似以下代码的内容在contextDestroyed()
的{{1}}方法中查找和关闭数据源:
ServletContextListener
但是,在尝试将DataSource转换为HikariDataSource时,我收到以下异常:
try
{
initContext = new InitialContext();
envContext = (Context) initContext.lookup("java:comp/env");
ds = (DataSource) envContext.lookup("jdbc/myDB");
if (ds.getConnection() == null)
{
throw new RuntimeException("Failed to find the JNDI Datasource");
}
logger.info("JNDI HikariDataSource : " + System.identityHashCode(ds.getClass()));
logger.info("Local HikariDataSource: " + System.identityHashCode(HikariDataSource.class));
HikariDataSource hds = (HikariDataSource) ds;
hds.close();
} catch (Exception ex)
{
logger.log(Level.SEVERE, null, ex);
}
我上面也得到了不同的identityHashCodes,这让我相信我有2个类加载器已经加载了HikariDataSource类的单独实例。我们希望数据源特定于webapp的上下文,并在热部署时关闭它。我需要改变什么才能实现这一目标?