Хотя Tomcat принудительно отменяет регистрацию драйвера JDBC для вас, тем не менее, хорошая практика - очистить все ресурсы, созданные вашим webapp, при уничтожении контекста, если вы перейдете в другой контейнер сервлетов, который не выполняет проверки безопасности утечки памяти, которые Tomcat делает.
Тем не менее, методология полного снятия регистрации водителя опасна. Некоторые драйверы, возвращаемые методом DriverManager.getDrivers()
, возможно, были загружены родительским ClassLoader (то есть загрузчиком классов контейнера сервлетов), а не классом ClassLoader для контекста webapp (например, они могут находиться в папке lib контейнера, а не в веб-папке, и поэтому совместно используются весь контейнер).
Поэтому следует проверить, что ClassLoader для каждого драйвера является ClassLoader Webapp, прежде чем отменять его регистрацию. Итак, в вашем контексте contextTestroyed () метода 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);
}
}
}
Это оператор splat . Вы часто будете видеть, что он используется для разделения массива на параметры функции.
def my_function(param1, param2, param3)
param1 + param2 + param3
end
my_values = [2, 3, 5]
my_function(*my_values) # returns 10
Чаще он используется для принятия произвольного количества аргументов
def my_other_function(to_add, *other_args)
other_args.map { |arg| arg + to_add }
end
my_other_function(1, 6, 7, 8) # returns [7, 8, 9]
Он также работает для множественного присваивания (хотя оба этих оператора будут работать без знак):
first, second, third = *my_values
*my_new_array = 7, 11, 13
Для вашего примера эти два будут эквивалентны:
p *1..10
p 1, 2, 3, 4, 5, 6, 7, 8, 9, 10