看源碼的時候發現能夠在
service
獲取request
和response
,正常來講在service
層是沒有request
的,然而直接從controlller
傳過來的話解決方法太粗暴,後來發現了SpringMVC提供的RequestContextHolder
來研究一下,並藉此對SpringMVC的結構深刻了解一下java
RequestContextHolder
顧名思義,持有上下文的Request
容器.使用是很簡單的,具體使用以下:spring
RequestAttributes requestAttributes = RequestContextHolder.currentRequestAttributes(); //RequestContextHolder.getRequestAttributes(); //從session裏面獲取對應的值 String str = (String) requestAttributes.getAttribute("name",RequestAttributes.SCOPE_SESSION); HttpServletRequest request = ((ServletRequestAttributes)requestAttributes).getRequest(); HttpServletResponse response = ((ServletRequestAttributes)requestAttributes).getResponse();
request和response怎麼和當前請求掛鉤?
request和response等是何時設置進去的?session
首先分析
RequestContextHolder
這個類,裏面有兩個ThreadLocal
保存當前線程下的requestspa
//獲得存儲進去的request private static final ThreadLocal<RequestAttributes> requestAttributesHolder = new NamedThreadLocal<RequestAttributes>("Request attributes"); //可被子線程繼承的request private static final ThreadLocal<RequestAttributes> inheritableRequestAttributesHolder = new NamedInheritableThreadLocal<RequestAttributes>("Request context");
再看
getRequestAttributes()
方法,至關於直接獲取ThreadLocal裏面的值,這樣就保證了每一次獲取到的Request是該請求的request.線程
public static RequestAttributes getRequestAttributes() { RequestAttributes attributes = requestAttributesHolder.get(); if (attributes == null) { attributes = inheritableRequestAttributesHolder.get(); } return attributes; }
找這個的話須要對springMVC結構的
DispatcherServlet
的結構有必定了解才能準確的定位該去哪裏找相關代碼.code
要分析的的就是三個類,簡單看下源碼繼承
HttpServletBean
進行初始化工做get
FrameworkServlet
初始化 WebApplicationContext
,並提供service方法預處理請源碼
DispatcherServlet
具體分發處理.it
那麼就能夠在FrameworkServlet
查看到該類重寫了service(),doGet(),doPost()...等方法,這些實現裏面都有一個預處理方法processRequest(request, response);
,因此定位到了咱們要找的位置
查看processRequest(request, response);
的實現,具體能夠分爲三步: