Хотя Tomcat принудительно отменяет регистрацию драйвера JDBC для вас, тем не менее, рекомендуется очистить все ресурсы, созданные вашим веб-приложением, при уничтожении контекста в случае, если вы переместитесь в другой контейнер сервлета, который не выполняет проверки предотвращения утечки памяти, как это делает Tomcat.
Однако методика отмены регистрации общего драйвера опасна. Некоторые драйверы, возвращаемые DriverManager.getDrivers()
методом, возможно, были загружены родительским ClassLoader (т. Е. Загрузчиком классов контейнера сервлета), а не ClassLoader контекста веб-приложения (например, они могут находиться в папке lib контейнера, а не в веб-приложении, и, следовательно, совместно использоваться по всему контейнеру). ). Отмена регистрации повлияет на любые другие веб-приложения, которые могут их использовать (или даже на сам контейнер).
Следовательно, следует проверить, что ClassLoader для каждого драйвера является ClassLoader веб-приложения, прежде чем отменять его регистрацию. Итак, в вашем методе contextDistener () вашего ContextListener:
public final void contextDestroyed(ServletContextEvent sce) {
// ... First close any background tasks which may be using the DB ...
// ... Then close any DB connection pools ...
// Now deregister JDBC drivers in this context's ClassLoader:
// Get the webapp's ClassLoader
ClassLoader cl = Thread.currentThread().getContextClassLoader();
// Loop through all drivers
Enumeration<Driver> drivers = DriverManager.getDrivers();
while (drivers.hasMoreElements()) {
Driver driver = drivers.nextElement();
if (driver.getClass().getClassLoader() == cl) {
// This driver was registered by the webapp's ClassLoader, so deregister it:
try {
log.info("Deregistering JDBC driver {}", driver);
DriverManager.deregisterDriver(driver);
} catch (SQLException ex) {
log.error("Error deregistering JDBC driver {}", driver, ex);
}
} else {
// driver was not registered by the webapp's ClassLoader and may be in use elsewhere
log.trace("Not deregistering JDBC driver {} as it does not belong to this webapp's ClassLoader", driver);
}
}
}