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

Java子線程調(diào)用RequestContextHolder.getRequestAttributes()方法問題詳解

 更新時間:2022年09月27日 09:43:51   作者:ypp91zr  
這篇文章主要介紹了Java子線程調(diào)用RequestContextHolder.getRequestAttributes()方法問題處理,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

相信很多開發(fā)過程中都用過RequestContextHolder.getRequestAttributes(),沒錯,我也經(jīng)常用,但今天出現(xiàn)了問題,獲取到的實(shí)例是空的

原因是因?yàn)槲倚麻_了一個子線程,在子線程調(diào)用了RequestContextHolder.getRequestAttributes()。實(shí)際獲取到的是空的

然后查看了源碼

ThreadLocal獲取。一個請求到達(dá)容器后,Spring會把該請求Request實(shí)例通過setRequestAttributes方法 把Request實(shí)例放入該請求線程內(nèi)ThreadLocalMap中,然后就可以通過靜態(tài)方法取到。原理就是ThreadLocal,但ThreadLocal不能讓子線程繼承ThreadLocalMap信息,可以使用InherbritableThreadLocal實(shí)現(xiàn)子線程信息傳遞。

Spring Boot 默認(rèn)使用ThreadLocal把Request設(shè)置進(jìn)請求線程中,這樣如果在請求方法里面另起一個子線程然后再通過getRequestAttributes方法獲取,是獲取不到的

如果想要在子線程獲取,設(shè)置inheritable=true即可,但我一直沒找到在哪里可以設(shè)置,于是自己就寫了個工具類來讓子線程獲取,思路是自定義一個注解,攔截注解,將父線程的ServletRequestAttributes給InheritableThreadLocal,然后在子線程即可獲取

package com.shinedata.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface RequestInheritableThread {
}

AOP

package com.shinedata.aop;
import com.shinedata.util.context.RequestHolder;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.ServletRequestAttributes;
@Aspect
@Component
public class RequestHolderAspect {
    @Before("@annotation(com.shinedata.annotation.RequestInheritableThread)")
    public void doBefore(JoinPoint joinPoint) {
        ServletRequestAttributes servletRequestAttributes = RequestHolder.getServletRequestAttributes();
        RequestHolder.setServletRequestAttributes(servletRequestAttributes);
    }
    @After("@annotation(com.shinedata.annotation.RequestInheritableThread)")
    public void doAfter(JoinPoint joinPoint) {
        RequestHolder.removeServletRequestAttributes();
    }
}

工具類

package com.shinedata.util.context;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.Map;
import java.util.StringTokenizer;
/**
 * @ClassName RequestHolder
 * @Author yupanpan
 */
public class RequestHolder {
    private static final Logger logger = LoggerFactory.getLogger(RequestHolder.class);
    public static final String GET = "GET";
    public static final String POST = "POST";
    public static final String UTF8 = "UTF-8";
    public static InheritableThreadLocal<ServletRequestAttributes> servletRequestAttributesInheritableThreadLocal= new InheritableThreadLocal();
    public static HttpServletRequest getRequest() {
        return getServletRequestAttributes().getRequest();
    }
    public static HttpServletResponse getResponse() {
        return getServletRequestAttributes().getResponse();
    }
    public static ServletRequestAttributes setServletRequestAttributes(ServletRequestAttributes servletRequestAttributes) {
        servletRequestAttributesInheritableThreadLocal.set(servletRequestAttributes);
        return servletRequestAttributes;
    }
    public static void removeServletRequestAttributes() {
        servletRequestAttributesInheritableThreadLocal.remove();
    }
    public static ServletRequestAttributes getServletRequestAttributes() {
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
        if(requestAttributes==null){
            requestAttributes=servletRequestAttributesInheritableThreadLocal.get();
        }
        return requestAttributes;
    }
}

需要在子線程獲取ServletRequestAttributes使用的時候在父方法貼個注解@RequestInheritableThread就行了,父方法里面即使開子線程,子線程里面也能獲取ServletRequestAttributes

補(bǔ)充第二種解決辦法,在開啟新線程之前,將RequestAttributes對象設(shè)置為子線程共享

//開啟新線程之前,添加代碼:
ServletRequestAttributes sra = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
RequestContextHolder.setRequestAttributes(sra, true);

到此這篇關(guān)于Java子線程調(diào)用RequestContextHolder.getRequestAttributes()方法問題詳解的文章就介紹到這了,更多相關(guān)Java RequestContextHolder.getRequestAttributes()內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Ribbon單獨(dú)使用,配置自動重試,實(shí)現(xiàn)負(fù)載均衡和高可用方式

    Ribbon單獨(dú)使用,配置自動重試,實(shí)現(xiàn)負(fù)載均衡和高可用方式

    這篇文章主要介紹了Ribbon單獨(dú)使用,配置自動重試,實(shí)現(xiàn)負(fù)載均衡和高可用方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-12-12
  • spring學(xué)習(xí)教程之@ModelAttribute注解運(yùn)用詳解

    spring學(xué)習(xí)教程之@ModelAttribute注解運(yùn)用詳解

    這篇文章主要給大家介紹了關(guān)于spring學(xué)習(xí)教程之@ModelAttribute注釋運(yùn)用的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起看看吧。
    2017-06-06
  • 一文教你如何使用AES對接口參數(shù)進(jìn)行加密

    一文教你如何使用AES對接口參數(shù)進(jìn)行加密

    這篇文章主要是想為大家介紹一下如何使用AES實(shí)現(xiàn)對接口參數(shù)進(jìn)行加密,文中的示例代碼簡潔易懂,具有一定的借鑒價值,需要的小伙伴可以了解一下
    2023-08-08
  • 實(shí)例講解Java讀取一般文本文件和word文檔的方法

    實(shí)例講解Java讀取一般文本文件和word文檔的方法

    讀取一般文本文件很好辦,調(diào)用Java自帶的io包里的類即可,富文本的doc文件我們可以用Apache的poi項(xiàng)目中的WordExtractor,這里我們一起來以實(shí)例講解Java讀取一般文本文件和word文檔的方法
    2016-06-06
  • springboot集成KoTime的配置過程

    springboot集成KoTime的配置過程

    koTime是一個springboot項(xiàng)目性能分析工具,通過追蹤方法調(diào)用鏈路以及對應(yīng)的運(yùn)行時長快速定位性能瓶頸,這篇文章主要介紹了springboot集成KoTime,需要的朋友可以參考下
    2022-06-06
  • 詳解Java多線程和IO流的應(yīng)用

    詳解Java多線程和IO流的應(yīng)用

    這篇文章主要介紹了詳解Java多線程和IO流的應(yīng)用,無論是本地文件復(fù)制,還是網(wǎng)絡(luò)多線程下載,對于流的使用都是一樣的,需要的朋友可以參考下
    2023-04-04
  • Java(springboot) 讀取txt文本內(nèi)容代碼實(shí)例

    Java(springboot) 讀取txt文本內(nèi)容代碼實(shí)例

    這篇文章主要介紹了Java(springboot) 讀取txt文本內(nèi)容代碼實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-02-02
  • Java中的內(nèi)存泄露問題和解決辦法

    Java中的內(nèi)存泄露問題和解決辦法

    大家好,本篇文章主要講的是Java中的內(nèi)存泄露問題和解決辦法,感興趣的同學(xué)趕快來看一看吧,對你有幫助的話記得收藏一下
    2022-01-01
  • java實(shí)現(xiàn)九宮格游戲

    java實(shí)現(xiàn)九宮格游戲

    這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)九宮格游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-11-11
  • 關(guān)于Openfire集群源碼的分析

    關(guān)于Openfire集群源碼的分析

    這篇文章主要介紹了關(guān)于Openfire集群源碼的分析,內(nèi)容比較詳細(xì),具有一定參考價值,需要的朋友可以了解下。
    2017-09-09

最新評論

广宗县| 都江堰市| 五河县| 方山县| 乐都县| 阿克陶县| 宣汉县| 英山县| 林口县| 临泽县| 祁阳县| 内丘县| 宁安市| 罗源县| 六枝特区| 长垣县| 澜沧| 宝应县| 宁南县| 蓬溪县| 兴国县| 浦北县| 临湘市| 长沙市| 邻水| 林州市| 望江县| 长乐市| 上高县| 凌海市| 隆回县| 塔河县| 左云县| 南涧| 福清市| 聂拉木县| 年辖:市辖区| 西乡县| 辽源市| 茂名市| 太保市|