用了Spring MVC有一个多月了,之前虽然有接触过一些,但是一直没有在实际工作中使用。今天和同事聊起,谈到Spring MVC中的Controller是单例实现的,于是就写了一段代码验证一些。
1. 如果是单例的,那么在Controller类中的实例变量应该是共享的,如果不共享,则说明不是单例。
直接代码:
@Controller
public class DemoAction {
private int i = 0;
@RequestMapping(value = "/singleton")
@ResponseBody
public String singleton(HttpServletRequest request, HttpServletResponse response) throws InterruptedException {
int addInt = Integer.parseInt(request.getParameter("int"));
i = i + addInt;
return String.valueOf(i);
}
}
分别三次请求: localhost:8080/projectname/singleton?int=5
得到的返回结果如下。
第一次: i=5
第二次: i=10
第三次: i=15
重结果可以得知,i的状态是共享的,因此Controller是单例的。
-------------------------------------------------------------------------------------------------------------------------
2. 如果是单例,那么多个线程请求同一个Controller类中的同一个方法,线程是否会堵塞?
验证代码如下:
@RequestMapping(value = "/switcher")
@ResponseBody
public String switcher(HttpServletRequest request, HttpServletResponse response)
throws InterruptedException {
String switcher = request.getParameter("switcher");
if (switcher.equals("on")) {
Thread.currentThread().sleep(10000);
return "switch on";
} else {
return switcher;
}
}
验证方法:
分别发送两个请求,
第一个请求:localhost:8080/projectname/singleton?switcher=on
第二个请求:localhost:8080/projectname/singleton?switcher=everything
验证结果:
第一个请求发出去以后,本地服务器等待10s,然后返回结果“switch on”,
在本地服务器等待的者10s当中,第二期的请求,直接返回结果“everything”。说明之间的线程是不互相影响的。
-------------------------------------------------------------------------------------------------------------------------
3.既然Controller是单例的,那么Service是单例的吗?验证方法和Controller的单例是一样的。
验证代码:
Controller:
@Controller
public class DemoAction {
@Resource
private DemoService demoService;
@RequestMapping(value = "/service")
@ResponseBody
public String service(HttpServletRequest request, HttpServletResponse response)
throws InterruptedException {
int result = demoService.addService(5);
return String.valueOf(result);
}
}
Service:
@Service
public class DemoService {
private int i = 0;
public int addService(int num){
i = i + num;
return i;
}
}
分别三次请求: localhost:8080/projectname/service
得到的返回结果如下。
第一次: i=5
第二次: i=10
第三次: i=15
重结果可以得知,i的状态是共享的,因此Service默认是单例的。
-------------------------------------------------------------------------------------------------------------------------
相同的验证方法,可以得出@Repository的DAO也是默认单例。
-----------------------------------------------------
Silence, the way to avoid many problems;
Smile, the way to solve many problems;