用了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;