springboot如何把HttpServletRequest傳入到controller

HttpServletRequest是由如tomcat這種Servlet容器創(chuàng)建的。
Tomcat 創(chuàng)建的 Request 和 Response 的類(lèi)結(jié)構(gòu)圖。

image.png

至于這個(gè)HttpServletRequest是怎么傳到你對(duì)應(yīng)的controller方法內(nèi)的,實(shí)際上就是SpringMVC里面的DispatchServlet起的作用。這里先不展開(kāi),下面再討論,先看一張圖。

image.png

得到HttpServletRequest的三種方式

方式一:Controller方法參數(shù)

Controller的方法參數(shù)上寫(xiě)上HttpServletRequest,這樣每次請(qǐng)求過(guò)來(lái)得到就是對(duì)應(yīng)的HttpServletRequest

@GetMapping("/test")
public void test(HttpServletRequest request) {}

方式二:從RequestContextHolder上下文獲取

    // 從請(qǐng)求上下文里獲取Request對(duì)象
    ServletRequestAttributes requestAttributes = ServletRequestAttributes.class.
        cast(RequestContextHolder.getRequestAttributes());
    HttpServletRequest contextRequest = requestAttributes.getRequest(); 

方式三:依賴(lài)注入@Autowired

@Autowired
HttpServletRequest req;
 
@GetMapping("/test")
public void test(HttpServletRequest request) {}

注入的request何處來(lái)?

image.png

發(fā)現(xiàn)是注入其實(shí)是往WebApplicationContextUtils通過(guò)RequestObjectFactory拿值,跟蹤

image

返回的是RequestContextHolder里的值. 追蹤RequestContextHolder

image.png

每次返回的其實(shí)是, RequestAttributes的實(shí)現(xiàn)類(lèi)ServletWebRequest(ServletRequestAttributes)里的request. 因?yàn)镽equestAttributes是屬于threadLocal的,所以注入的request也是線(xiàn)程安全的了

2, spring何時(shí)設(shè)置的request對(duì)象?

HttpServlet實(shí)現(xiàn)類(lèi) FrameworkServlet-> service()->processRequst()

image

每次請(qǐng)求都會(huì)往里面設(shè)置最新的request, 設(shè)值

================================================================

我們可以在Spring的bean中輕松的注入HttpServletRequest,使用@Autowired HttpServletRequest request;就可以了。

但是,為什么我們可以直接這樣用呢?

原因肯定是Spring在容器初始化的時(shí)候就將HttpServletRequest注冊(cè)到了容器中。

那么我們就查原碼,發(fā)現(xiàn)在WebApplicationContextUtils.registerWebApplicationScopes(ConfigurableListableBeanFactory, ServletContext)中實(shí)現(xiàn)了這個(gè)功能。

這個(gè)方法是在A(yíng)bstractApplicationContext.refresh()中進(jìn)行調(diào)用的,也就是在Spring容器初始化的時(shí)候,將web相關(guān)的對(duì)象注冊(cè)到了容器中。

具體可以看下面的原碼圖片:

image
image
image
image

附:

1. Spring能實(shí)現(xiàn)在多線(xiàn)程環(huán)境下,將各個(gè)線(xiàn)程的request進(jìn)行隔離,且準(zhǔn)確無(wú)誤的進(jìn)行注入,奧秘就是ThreadLocal

image

2. Spring中還可以直接注入ApplicationContext

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀(guān)點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容