我知道通常不会这样做,而且我在网上发现了很多关于这个问题的实例,答案都是这样的:“如果你需要这样做,你的设计是错误的。”让我解释一下我的目标。
我有一个 Web 应用程序在某个站点以某种方式导致重复调用一个 servlet 的 init() 方法。我不知道这是怎么发生的,我不能重复。然而,从二进制堆转储(由内存不足异常引起)来看,从堆上的对象可以清楚地看出特定 servlet 的 init() 方法被调用了大约 10,000 次,因为这是这些对象唯一的地方被创建,并且有一个对象的 10,000 多个实例应该不超过一个实例。
由于我无法重现在这个站点上发生的情况,因此我想在此 servlet 上强制调用 init() 多次,最好是通过 JSP 文件,这样我就可以在应用修复前后进行测试。测试“之后”的情况在理论上很容易,因为我可以更改代码以(例如)将此 servlet 粘贴到上下文中,这样我就可以获取它并重复调用 init() 以证明此对象没有泄漏。但这并不能帮助我用现有代码测试“之前”的情况。
我不能在 JSP 中只使用“(new MyServlet()).init()”。这会失败,因为 servlet 是使用空上下文创建的并且无法初始化。到 Tomcat 5.5,似乎 ServletContext.getServlets() 总是返回一个空 Enumeration,而 ServletContext.getServlet(String) 总是返回 null。
似乎最简单的测试方法是我是否可以以某种方式(最好是从 JSP)访问有问题的 servlet 实例,或者以编程方式将新映射添加到同一个 servlet 类,这可能会创建新实例。 (?)
最佳答案
您已经发现您正在尝试的是非常不寻常的,并且远非最佳实践,因此我不会详细讨论该主题。话虽如此,如果您想在 Tomcat 中运行的 MyServlet
实例上多次调用 MyServlet.init()
,您可以子类化 MyServlet
,重写doGet()
或doPost()
方法,添加一个简单调用this.init();
1000次的循环,然后调用父类 doGet()
/doPost()
。编辑 WEB-INF/web.xml
以使用您的子类代替 MyServlet
。然后只需使用 Web 浏览器点击 servlet,就会看到 init()
在正常提供页面之前调用了 1000 次。而且您根本没有修改原始的 MyServlet
类,保持您的 before 测试纯净。
关于java - 使用 Tomcat 5.5,如何以编程方式定位特定的 servlet 实例或添加新的映射?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6234618/