spring mvc的Controller和其它bean一样,默认是单例bean,也就是spring mvc的Controller的实例只有一个.当在Controller声明实例变量时,当有多个请求,有可能A请求改变这个变量,B请求得到的是A请求设置的值.
设计:设计有10个用户,这10个用户同时都去发送http://192.168.0.114:8080/upload/test?username=u1&password=p1和http://192.168.0.114:8080/upload/test?username=u2&password=p2.其中测试工具jmeter.新建一个测试计划,在这个测试计划添加一个线程组,设置线程数为10(相当于10个用户),ramp-up period(in seconds)设为0,循环次数设为1,在这个线程组中添加两个http请求,两个http请求ip都填192.168.0.114和端口都填8080,一个请求路径填/upload/test?username=u1&password=p1,另一个请求路径填/upload/test?username=u2&password=p2.
Spring Controller关键代码:
@Controller
@RequestMapping("/upload")
public class UploadController {
private String name=null;
private String pass=null;
@RequestMapping(value = "/test")
public void test(String username,String password) throws IOException{
name=username;
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
pass=password;
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(name+":"+pass);
}
}
u1:p1
u1:p1
u1:p1
u2:p1
u2:p1
u2:p1
u2:p1
u2:p1
u2:p1
u2:p1
u2:p2
u2:p2
u2:p2
u2:p2
u2:p2
u2:p2
u2:p2
u2:p2
u2:p2
u2:p2
从结果来看,请求刚好20个,但理论要求是10个u1:p1和10个u2:p2.很明显,这里不符合要求,就出现多线程问题.所以spring controller是不能设置可改变的共享实例变量(不是不能设置可共用的不变的变量,比如private final static SimpleDateFormat sdf=new SimpleDateFormat("yyyyMM");,其实这个sdf应理解成静态常量,而不是实例变量,即使不要修饰符final static此种情况也可以).
有时间真要研究下spring,struts2,struts1的源码.