Управление методом destroy ()

Я пытаюсь корректно завершить работу приложения. Поэтому, когда запускается завершение работы приложения, мне нужно заставить процесс завершения работы ждать заданное количество секунд, в течение этого времени я все равно обслуживаю несколько запросов.

Я пытался использовать wait / sleep в методе destroy (), но на этом этапе контекст уже уничтожен. Насколько я понимаю, контейнер вызывал бы метод destroy (). Можно ли контролировать метод уничтожения и отсрочить начало процесса выключения?

Спасибо.


person Aswin Selvakumar    schedule 06.04.2017    source источник


Ответы (1)


Данный подход не будет работать. Причина в destroy() методе. Каждый сервлет будет иметь свой собственный destroy() метод. Этот метод вызывается, когда сервлет выгружается контейнером, а не когда ваше приложение завершает работу. Сервлеты могут быть выгружены, когда контейнер не будет использовать сервлет. Вы можете запустить ваше приложение, но ваш сервлет может быть выгружен контейнером, потому что контейнер может решить, что эти сервлеты не нужны.

Решение. Возможно, вам понадобится ServletContextListener. ServletContext связан со всем вашим приложением, а не только с одним сервлетом. Когда ваше приложение загружается, вызывается contextInitialized() ServletContextListener, а когда ваше приложение выгружается, вызывается contextDestroyed(). Таким образом, в contextDestroyed() вы можете засыпать поток и выполнять другую задачу.

    @WebListener
    public class MyContextListener implements ServletContextListener
    {

        public void contextInitialized(ServletContextEvent event)
        { 
         System.out.println("\n \n \n \n ServletContext is being initialized..... \n \n \n");
            }

        //Perform cleanups like removing DB connection.closing session etc. while closing appliction
        public void contextDestroyed(ServletContextEvent event)
        {
            try{
            //Sleep this thread.
            Thread.sleep(10000);
            } catch(Exception ex){ ex.printStackTrace(System.err); }
        }
    }
person Shadab Faiz    schedule 06.04.2017
comment
У меня есть ServletContextListener в моем приложении, и я сначала пробовал этот подход, но, как оказалось, contextDestroyed будет вызываться только тогда, когда контекст вот-вот будет отключен. Это просто уведомление о том, что сервер выходит из строя, и к этому времени контекст уже пропал, и это не помогает .. - person Aswin Selvakumar; 06.04.2017
comment
@AswinSelvakumar, вы неправильно поняли ServletContext. Для каждого веб-приложения существует только и только 1 ServletContext, а не ваш сервер. ContextDestroyed - это уведомление о том, что приложение выгружается с сервера, а не сервер выключается. Это две разные вещи. Сказав это, я считаю, что неправильно понял вашу точку зрения «пытаясь изящно завершить работу моего приложения». Под выключением вы имеете в виду удаление приложения с сервера или это все равно что выйти из приложения или закрыть вкладку, на которой используется ваше приложение. - person Shadab Faiz; 07.04.2017
comment
Я не удаляю приложение, просто выхожу из системы ... Допустим, у меня есть список Http в моем приложении, которое прослушивает порт 8080. Теперь я отключаю свое приложение, и слушатель исчезнет как Что ж. И мне нужно отложить отключение сервера, чтобы я мог обработать ожидающий запрос Http. Надеюсь, я подробно объяснил .. любые указатели, пожалуйста ..?! TIA .. - person Aswin Selvakumar; 07.04.2017
comment
Нет, спит в ServletContextListener::contextDestoyed реализация метода не достигнет цели, позволяющей сервлету выполнять больше работы. К тому времени сервлеты уже остановились. Согласно документу класса: Все сервлеты и фильтры будут уничтожены до того, как какие-либо ServletContextListeners будут уведомлены об уничтожении контекста. - person Basil Bourque; 19.04.2017