亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

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

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

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

原因是因為我新開了一個子線程,在子線程調(diào)用了RequestContextHolder.getRequestAttributes()。實際獲取到的是空的

然后查看了源碼

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

Spring Boot 默認使用ThreadLocal把Request設(shè)置進請求線程中,這樣如果在請求方法里面另起一個子線程然后再通過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

補充第二種解決辦法,在開啟新線程之前,將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)文章

  • IDEA新建Springboot項目(圖文教程)

    IDEA新建Springboot項目(圖文教程)

    下面小編就為大家?guī)硪黄狪DEA新建Springboot項目(圖文教程)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-07-07
  • 詳解java如何處理各種批量數(shù)據(jù)入庫

    詳解java如何處理各種批量數(shù)據(jù)入庫

    這篇文章主要為大家詳細介紹了java如何使用BlockingQueue處理各種批量數(shù)據(jù)入庫,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2023-11-11
  • Java后臺返回和處理JSon數(shù)據(jù)的方法步驟

    Java后臺返回和處理JSon數(shù)據(jù)的方法步驟

    這篇文章主要介紹了Java后臺返回和處理JSon數(shù)據(jù)的方法步驟,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-09-09
  • 利用Spring插件實現(xiàn)策略模式的案例詳解

    利用Spring插件實現(xiàn)策略模式的案例詳解

    Spring插件提供了一種更實用的插件開發(fā)方法,它提供了插件實現(xiàn)擴展核心系統(tǒng)功能的核心靈活性,但當然不提供核心OSGi功能,如動態(tài)類加載或運行時安裝和部署插件,本文就來聊下如何使用spring插件來實現(xiàn)策略模式,需要的朋友可以參考下
    2023-05-05
  • SpringBoot異常處理器的使用與添加員工功能實現(xiàn)流程介紹

    SpringBoot異常處理器的使用與添加員工功能實現(xiàn)流程介紹

    設(shè)計完了登錄與退出功能還只完成了冰山一角,經(jīng)過測試發(fā)現(xiàn),我們以url的方式來訪問網(wǎng)站時可以直接跳過登陸頁面進入后臺頁面,這樣顯然是不合理的,下面我們通過異常攔截器+boot來做到訪問限制,以及實現(xiàn)新增員工功能,制作全局異常處理器
    2022-10-10
  • SpringBoot項目運行jar包啟動的步驟流程解析

    SpringBoot項目運行jar包啟動的步驟流程解析

    這篇文章主要介紹了SpringBoot項目運行jar包啟動的步驟流程,本文分步驟通過圖文并茂的形式給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友參考下吧
    2020-07-07
  • springmvc如何進行異常處理

    springmvc如何進行異常處理

    這篇文章主要介紹了springmvc如何進行異常處理,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2019-09-09
  • SpringBoot 防御 CSRF 攻擊的流程及原理解析

    SpringBoot 防御 CSRF 攻擊的流程及原理解析

    CSRF是一種非常常見的Web攻擊方式,其實是很好防御的,但是由于經(jīng)常被很多開發(fā)者忽略,進而導(dǎo)致很多網(wǎng)站實際上都存在 CSRF 攻擊的安全隱患,這篇文章主要介紹了SpringBoot 如何防御 CSRF 攻擊,需要的朋友可以參考下
    2023-05-05
  • Servlet虛擬路徑映射配置詳解

    Servlet虛擬路徑映射配置詳解

    這篇文章主要介紹了Servlet虛擬路徑映射配置詳解,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-02-02
  • Java實現(xiàn)二叉搜索樹的插入、刪除功能

    Java實現(xiàn)二叉搜索樹的插入、刪除功能

    這篇文章主要介紹了Java實現(xiàn)二叉搜索樹的插入、刪除,本文通過實例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-01-01

最新評論