X.d 笔记

小Web,大世界

0%

由单例模式想到的MVC框架问题

今天忽然看到几篇博客,一个说 Servlet 是单例的,一个说不是单例的,于是自己试下。

废话不说上代码:

web.xml

 <servlet>
  <servlet-name>Test</servlet-name>
  <servlet-class>com.xdnote.test.TestServlet</servlet-class>
 </servlet>
 <servlet-mapping>
  <servlet-name>Test</servlet-name>
  <url-pattern>/test</url-pattern>
 </servlet-mapping>

TestServlet.java

private int time=0;
public void doGet(HttpServletRequest request, HttpServletResponse response)
{
    String id=request.getParameter("id");
    this.time=Integer.parseInt(request.getParameter("time"));
    System.out.println(id+":"+time);
    try {
        Thread.sleep(time);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    System.out.println(id+":"+time);
}

先请求test?id=6&time=6000
过1秒后再请求 test?id=10&time=10000
结果如下:
6:6000
10:10000
6:10000
10:10000

可见第三个6秒时的time被改为了10000,说明servlet是单例的。

结果就是这样,虽然如果不用Thread,很少重现,但一但出现就会摸不着头脑。
这样的代码让我马上想起了Struts。Struts2里面使用 Action 和 Servlet 有点类似,执行时会先 set 操作,由于不是 Servlet 所以不会单例。但是目前极度崇尚手 ssh 框架会让你不加思索的去配置一个 Spring,谁都知道 Spring 的核心是单例,减少 new 操作提高性能。可能就会这么写,把一个action变成单例。

<!-- struts.xml -->
<action name="testAction" class="testAction"></action>
<!-- application.xml -->
<bean id="testAction" class="com.xdnote.action.testAction"></bean>

很多书或文章都会教人这样结合 Struts 和 Spring,但用的时候就得注意了!!!,这里要是出了问题,重现也比较麻烦,损失还是相当大的。