我有一个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上。
答案 0 :(得分:0)
好主啊,很棒,你甚至相信内存泄漏吗?在servlet中运行一个线程?!你需要通过上下文监听器((在init()方法中,启动一个Thread来执行某个db 维护每小时运行一次)
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代码,我们将不胜感激。