最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Springboot注入成員變量HttpServletRequest的原理分析

 更新時間:2024年05月29日 09:20:51   作者:fenglllle  
這篇文章主要介紹了Springboot注入成員變量HttpServletRequest的原理分析,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教

前言

最近做項目,springboot項目,本來我們在controller的requestmapping取參數(shù)值或者返回寫時,使用方法參數(shù),但是發(fā)現(xiàn)老項目直接注入了成員變量,Spring本身是單例的,如果是成員變量注入,那么也是單例的,怎么實現(xiàn)不同的請求讀取不同的參數(shù)呢,如果實現(xiàn)線程安全呢,筆者立馬想到了ThreadLocal,但是如果要說就是這個原理,那么必須源碼證明。

準備demo

簡單寫一個demo

@RestController
public class DemoController {
 
    @Autowired
    private HttpServletRequest request;
 
    @GetMapping("/hello")
    public String demo(String param) {
        request.getParameterMap().forEach((k,v)-> System.out.println(k + " : " + Arrays.toString(v)));
        return param + ":hello";
    }
}

只寫了 HttpServletRequest,實際上HttpServletResponse亦是如此。

分析demo,注入的HttpServletRequest是接口類型,那么在Boot啟動中就會動態(tài)代理實現(xiàn),由于是接口,可以推測是JDK動態(tài)代理,debug果然如此。

源碼分析

根據(jù)debug,JDK動態(tài)代理注入了接口的實現(xiàn)類,關鍵在于InvocationHandler

Spring使用如下:

org.springframework.beans.factory.support.AutowireUtils.ObjectFactoryDelegatingInvocationHandler

里面有關鍵代碼

return method.invoke(this.objectFactory.getObject(), args);

this.objectFactory.getObject()這句決定線程安全

看看Spring Bean下JDK是怎么動態(tài)代理注入的

可以看到JDK動態(tài)代理在Spring注入的時候,把這個factory注入了InvocationHandler

其中的handler的invoke方法,這里實際上還要其他類的讀取埋點。

這里的invoke僅僅是反射,關鍵還是 HttpServletRequest的對象來源,跟蹤讀取邏輯

org.springframework.web.context.request.RequestContextHolder

到此就明確了,注入的成員變量,動態(tài)代理后使用Threadlocal處理,所以線程安全,因為每次請求都是線程請求,那么原始的HttpServletRequest對象怎么塞進去的呢,就要看filter的了

org.springframework.web.filter.RequestContextFilter

在doFilter時,執(zhí)行

同理在org.springframework.web.servlet.FrameworkServlet也會再次讀取和寫入

這里是為了,如果filter被去除的時候可以有值,再次保底,并且在結束時rest

只不過這個rest有點奇怪

對象并沒有清除,還在,說明即使 FrameworkServlet后還可以獲取,因為有filter可能會在這個后面執(zhí)行,如果干掉,很可能就不能讀取了。

會在RequestContextFilter后面remove;如果我們去掉這個filter,那么需要自定義一個filter實現(xiàn)remove防止內存泄漏。

清除當前線程及子線程ThreadLocal

public static void resetRequestAttributes() {
    requestAttributesHolder.remove();
    inheritableRequestAttributesHolder.remove();
}

至此 HttpServletRequest的成員變量注入邏輯,即ThreadLocal變量,所以請求可以正常訪問

總結

實際上這種用法很多項目都用了,只不過我們寫代碼下意思的通過方法參數(shù)來規(guī)避線程安全性,這種想法是有益的,可以從源頭規(guī)避風險,不過實際上Spring也幫我們考慮了這個問題,相當于使用RequestContextFilter做了保底措施。

源碼分析實際上是知所以然,尤其是我們自己寫公共SDK時,可以把這種設計放在代碼中,實現(xiàn)優(yōu)雅和保底邏輯。

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關文章

  • IDEA修改java文件后 不用重啟Tomcat服務便可實現(xiàn)自動更新

    IDEA修改java文件后 不用重啟Tomcat服務便可實現(xiàn)自動更新

    這篇文章主要介紹了IDEA修改java文件后 不用重啟Tomcat服務便可實現(xiàn)自動更新,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-11-11
  • Java遠程調用組件Feign技術使用詳解

    Java遠程調用組件Feign技術使用詳解

    Feign是Netflix公司開發(fā)的一個聲明式的REST調用客戶端; Ribbon負載均衡、 Hystrⅸ服務熔斷是我們Spring Cloud中進行微服務開發(fā)非?;A的組件,在使用的過程中我們也發(fā)現(xiàn)它們一般都是同時出現(xiàn)的,而且配置也都非常相似
    2022-11-11
  • ExecutorService實現(xiàn)獲取線程返回值

    ExecutorService實現(xiàn)獲取線程返回值

    這篇文章主要介紹了ExecutorService實現(xiàn)獲取線程返回值,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-08-08
  • feign客戶端設置超時時間操作

    feign客戶端設置超時時間操作

    這篇文章主要介紹了feign客戶端設置超時時間操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-09-09
  • 基于Springboot的高校社團管理系統(tǒng)的設計與實現(xiàn)

    基于Springboot的高校社團管理系統(tǒng)的設計與實現(xiàn)

    本文將基于Springboot+Mybatis開發(fā)實現(xiàn)一個高校社團管理系統(tǒng),系統(tǒng)包含三個角色:管理員、團長、會員。文中采用的技術有Springboot、Mybatis、Jquery、AjAX、JSP等,感興趣的可以了解一下
    2022-07-07
  • Java中Spring擴展點詳解

    Java中Spring擴展點詳解

    這篇文章主要介紹了Java中Spring技巧之擴展點的應用,下文Spring容器的啟動流程圖展開其內容的相關資料,具有一定的參考價值,需要的小伙伴可以參考一下
    2022-06-06
  • java秒殺系統(tǒng)常見問題庫存超賣解決實例分析

    java秒殺系統(tǒng)常見問題庫存超賣解決實例分析

    這篇文章主要為大家介紹了java秒殺系統(tǒng)常見問題庫存超賣解決實例分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-11-11
  • Java設計模式之訪問者模式

    Java設計模式之訪問者模式

    這篇文章介紹了Java設計模式之訪問者模式,文中通過示例代碼介紹的非常詳細。對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-10-10
  • 淺談Java中實現(xiàn)深拷貝的兩種方式—clone() & Serialized

    淺談Java中實現(xiàn)深拷貝的兩種方式—clone() & Serialized

    這篇文章主要介紹了Java中實現(xiàn)深拷貝的兩種方式—clone() & Serialized,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-03-03
  • 一文帶你了解Java設計模式之原型模式

    一文帶你了解Java設計模式之原型模式

    原型模式其實就是從一個對象在創(chuàng)建另外一個可定制的對象,不需要知道任何創(chuàng)建的細節(jié)。本文就來通過示例為大家詳細聊聊原型模式,需要的可以參考一下
    2022-09-09

最新評論

河北省| 西安市| 武冈市| 黄大仙区| 镇远县| 丰原市| 石柱| 侯马市| 永州市| 泽州县| 利辛县| 财经| 中西区| 突泉县| 阿拉善左旗| 德兴市| 保亭| 保德县| 当涂县| 南安市| 合肥市| 耒阳市| 什邡市| 三穗县| 德昌县| 阿克陶县| 揭东县| 汶上县| 庐江县| 灵宝市| 郁南县| 屏南县| 武平县| 嫩江县| 伊宁县| 榆中县| 柳林县| 出国| 盈江县| 司法| 阿巴嘎旗|