RequestDispatcher实例化已经通过load-on-startup实例化的servlet

时间:2015-08-05 10:33:33

标签: tomcat servlets requestdispatcher

我有一个Servlet,注释如下:

@WebServlet(value="/MyServiceServlet", loadOnStartup=1)

这导致Servlet在应用程序启动时被实例化,并且其init()方法被调用。完善! (在init()方法中,启动一个Thread来执行一些每小时运行的数据库维护)

现在,在某些最终用户操作上,我通过使用来访问Servlet getServletContext().getRequestDispatcher("/MyServiceServlet").include(request, response)触发一些其他数据库的东西,但是第一次尝试这个时,我的Servlet再次被实例化,并且init()方法被调用(当然),这导致两个类似的线程运行。不完美!

似乎loadOnStartup=1没有将Servlet放在Servlet上下文中,因此当我尝试通过Request Dispatcher访问它时,它需要实例化。

这怎么可能?如何修复所以我只得到一个我的Servlet实例?我需要在应用程序中启动它,因为init()中启动的服务应立即运行。

该应用程序部署在Tomcat 7.0.57上。

1 个答案:

答案 0 :(得分:0)

  

(在init()方法中,启动一个Thread来执行某个db   维护每小时运行一次)

好主啊,很棒,你甚至相信内存泄漏吗?在servlet中运行一个线程?!你需要通过上下文监听器(javax.servlet.ServletContextListener)来做,而不是直接做,这是不安全的。

public class run_thread implements ServletContextListener{
    @Override
        public void contextInitialized(ServletContextEvent sce) {System.out.println("Init: daemon stuffs");/*run teh trhead*/}
        @Override public void contextDestroyed(ServletContextEvent sce) {
            System.out.println("Hult: daemon stuffs");/*hult teh trhead*/
        }
    }

并且不要将其注册为bi web.xml

<listener>
    <listener-class>pack.run_thread</listener-class>
</listener>

更好的解决方案让另一个外部应用程序进行数据库维护,或者至少调用servlet路径来进行间隔维护。

  

现在,在某些最终用户操作上,我使用

到达Servlet

用户操作是什么?怎么样?使用另一个servlet?那么requets.getRequestDispatcher()而不是getServletContext()

呢?

您可以分享servlet代码,我们将不胜感激。