欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

SpringBoot?異步線程間傳遞上下文方式

 更新時(shí)間:2021年11月20日 16:46:14   作者:ye17186  
這篇文章主要介紹了SpringBoot?異步線程間傳遞上下文方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

異步線程間傳遞上下文

需求

SpringBoot項(xiàng)目中,經(jīng)常使用@Async來開啟一個(gè)子線程來完成異步操作。主線程中的用戶信息需要傳遞給子線程

實(shí)現(xiàn)

啟用異步功能

在啟動(dòng)類里加上@EnableAsync注解

@EnableAsync
@SpringBootApplication
public class Application {}

配置異步

新建一個(gè)配置類,實(shí)現(xiàn)AsyncConfigurer接口,并重寫getAsyncExecutor方法

@Configuration
public class AsyncConfig implements AsyncConfigurer {
    @Override
    public Executor getAsyncExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(10);
        executor.setMaxPoolSize(50);
        executor.setThreadNamePrefix("async-pool-");
        // 這一步是關(guān)鍵,異步Task裝飾器
        executor.setTaskDecorator(new MyContextDecorator());
        executor.initialize();
        return executor;
    }
}

配置任務(wù)裝飾器

新建一個(gè)異步任務(wù)裝飾器,實(shí)現(xiàn)TaskDecorator接口,并重寫decorate方法

public class MyContextDecorator implements TaskDecorator {
    @Override
    @Nonnull
    public Runnable decorate(@Nonnull Runnable runnable) {
  // 獲取主線程中的請(qǐng)求信息(我們的用戶信息也放在里面)
       RequestAttributes attributes = RequestContextHolder.getRequestAttributes();
        return () -> {
            try {
               // 將主線程的請(qǐng)求信息,設(shè)置到子線程中
               RequestContextHolder.setRequestAttributes(attributes);
              // 執(zhí)行子線程,這一步不要忘了
                runnable.run();
            } finally {
             // 線程結(jié)束,清空這些信息,否則可能造成內(nèi)存泄漏
                RequestContextHolder.resetRequestAttributes();
            }
        };
    }

補(bǔ)充下:RequestContextHolder內(nèi)部是基于ThreadLocal實(shí)現(xiàn)的,因此在使用set get時(shí),都是和當(dāng)前線程綁定的。當(dāng)然,使用者的用戶信息不一定放在了RequestContextHolder里面,讀者可以自行擴(kuò)展。

到此,通過@Async開啟的子線程,就可以正常拿到父線程中的Request信息了。

啟用多線程安全上下文無法在線程間共享問題

問題

項(xiàng)目中多線程添加數(shù)據(jù),mybatisplus元數(shù)據(jù)填充功能,填充創(chuàng)建人時(shí),數(shù)據(jù)是來自 spring security SecurityContextHolder.getContext.getAuthentication,同步操作時(shí),能正常獲取,而異步執(zhí)行時(shí)空指針異常。

解決方案

配置安全上下文全局策略SecurityContextHolder.setStrategyName(SecurityContextHolder.MODE_INHERITABLETHREADLOCAL)

原理

Spring Security 安全上下文默認(rèn)策略為MODE_THREADLOCAL,ThreadLocal機(jī)制來保存每個(gè)使用者的安全上下文。

這意味著,只要針對(duì)某個(gè)使用者的邏輯執(zhí)行都是在同一個(gè)線程中進(jìn)行,即使不在各個(gè)方法之間以參數(shù)的形式傳遞其安全上下文,各個(gè)方法也能通過SecurityContextHolder工具獲取到該安全上下文。

只要在處理完當(dāng)前使用者的請(qǐng)求之后注意清除ThreadLocal中的安全上下文,這種使用ThreadLocal的方式是很安全的。

  • MODE_GLOBAL: JVM中所有的線程使用同一個(gè)安全上下文
  • MODE_INHERITABLETHREADLOCAL:有些應(yīng)用會(huì)有自己的線程創(chuàng)建,并且希望這些新建線程也能使用創(chuàng)建者的安全上下文。這種效果,可以通過將SecurityContextHolder配置成MODE_INHERITABLETHREADLOCAL策略達(dá)到。

結(jié)果

在配置文件中添加:

@PostConstruct
public void init(){
    SecurityContextHolder.setStrategyName(SecurityContextHolder.MODE_INHERITABLETHREADLOCAL);
}
 

@PostConstruct注解好多人以為是Spring提供的。其實(shí)是Java自己的注解。

Java中該注解的說明:@PostConstruct該注解被用來修飾一個(gè)非靜態(tài)的void()方法。被@PostConstruct修飾的方法會(huì)在服務(wù)器加載Servlet的時(shí)候運(yùn)行,并且只會(huì)被服務(wù)器執(zhí)行一次。PostConstruct在構(gòu)造函數(shù)之后執(zhí)行,init()方法之前執(zhí)行。

通常我們會(huì)是在Spring框架中使用到@PostConstruct注解 該注解的方法在整個(gè)Bean初始化中的執(zhí)行順序:

Constructor(構(gòu)造方法) -> @Autowired(依賴注入) -> @PostConstruct(注釋的方法)

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

相關(guān)文章

  • Java實(shí)現(xiàn)MD5加密的方法

    Java實(shí)現(xiàn)MD5加密的方法

    這篇文章主要介紹了Java實(shí)現(xiàn)MD5加密的方法,實(shí)例分析了基于java實(shí)現(xiàn)md5加密的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-07-07
  • Java實(shí)現(xiàn)注冊(cè)登錄與郵箱發(fā)送賬號(hào)驗(yàn)證激活功能

    Java實(shí)現(xiàn)注冊(cè)登錄與郵箱發(fā)送賬號(hào)驗(yàn)證激活功能

    這篇文章主要介紹了Java實(shí)現(xiàn)注冊(cè)登錄與郵箱發(fā)送賬號(hào)驗(yàn)證激活功能,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧
    2022-12-12
  • java中關(guān)于文本文件的讀寫方法實(shí)例總結(jié)

    java中關(guān)于文本文件的讀寫方法實(shí)例總結(jié)

    這篇文章主要介紹了java中關(guān)于文本文件的讀寫方法,實(shí)例總結(jié)了Java針對(duì)文本文件讀寫的幾種常用方法,并對(duì)比了各個(gè)方法的優(yōu)劣及特點(diǎn),具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-11-11
  • 詳解json在SpringBoot中的格式轉(zhuǎn)換

    詳解json在SpringBoot中的格式轉(zhuǎn)換

    這篇文章主要介紹了詳解json在SpringBoot中的格式轉(zhuǎn)換,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-11-11
  • Java中的取余與取模運(yùn)算概念、區(qū)別代碼實(shí)踐

    Java中的取余與取模運(yùn)算概念、區(qū)別代碼實(shí)踐

    這篇文章主要介紹了Java中的取余與取模運(yùn)算概念、區(qū)別代碼實(shí)踐,需要的朋友可以參考下
    2007-02-02
  • win7下安裝 JDK 基本流程

    win7下安裝 JDK 基本流程

    這篇文章主要介紹了win7下安裝 JDK 基本流程,需要的朋友可以參考下
    2014-05-05
  • spring定時(shí)器@Scheduled異步調(diào)用方式

    spring定時(shí)器@Scheduled異步調(diào)用方式

    在Spring Boot中,@Schedule默認(rèn)使用單線程執(zhí)行定時(shí)任務(wù),多個(gè)定時(shí)器會(huì)按順序執(zhí)行,為實(shí)現(xiàn)異步執(zhí)行,可以通過自定義線程池或?qū)崿F(xiàn)SchedulingConfigurer接口,使用自定義線程池可以保證多個(gè)定時(shí)器并發(fā)執(zhí)行
    2024-11-11
  • Java中的JSONObject使用及錯(cuò)誤處理詳解

    Java中的JSONObject使用及錯(cuò)誤處理詳解

    這篇文章主要給大家介紹了關(guān)于Java中的JSONObject使用及錯(cuò)誤處理的相關(guān)資料,文中講解了Java中的JSONObject創(chuàng)建、基本操作、高級(jí)特性和錯(cuò)誤處理,通過示例代碼和方法說明,使讀者能夠理解和掌握J(rèn)SONObject的使用技巧,需要的朋友可以參考下
    2024-12-12
  • Java使用Redis實(shí)現(xiàn)微博熱搜功能

    Java使用Redis實(shí)現(xiàn)微博熱搜功能

    在社交平臺(tái)上,熱搜功能是一個(gè)非常重要的組成部分,它展示了當(dāng)前最熱門的話題,幫助用戶迅速了解最受關(guān)注的事件,Redis 是一個(gè)高性能的鍵值存儲(chǔ)系統(tǒng),通常用于緩存和實(shí)時(shí)數(shù)據(jù)存儲(chǔ),本文將通過 Java 結(jié)合 Redis 實(shí)現(xiàn)一個(gè)簡(jiǎn)化版的微博熱搜功能,需要的朋友可以參考下
    2024-12-12
  • 關(guān)于Spring MVC在Controller層中注入request的坑詳解

    關(guān)于Spring MVC在Controller層中注入request的坑詳解

    這篇文章主要給大家介紹了關(guān)于Spring MVC在Controller層中注入request的坑的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。
    2018-04-04

最新評(píng)論