異步任務獲取springSecurity主線程上下文信息失敗


一、首先配置好的@Async線程池配置類

@EnableAsync
@Configuration
public class AsyncTaskConfig implements AsyncConfigurer { @Override public Executor getAsyncExecutor() { ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor(); taskExecutor.setCorePoolSize(1);// 最小線程數 taskExecutor.setMaxPoolSize(10);// 最大線程數 taskExecutor.setQueueCapacity(25);// 等待隊列 taskExecutor.setWaitForTasksToCompleteOnShutdown(true);// 等待所有任務結束后再關閉線程池  taskExecutor.initialize(); return taskExecutor; } }

在注解@Async中調用的方法中如果使用security來獲取用戶信息應該是獲取不到的,原因是異步任務開啟了新線程,所以用的登錄信息不能在子線程獲取,只能在主線程獲取,因為securityContextHolder默認將用戶信息保存在了ThreadLocal

主線程Security信息,即調用異步方法之前線程:

 

子線程security信息,即調用異步方法之后信息,可以看到getUserInfo為null,什么也沒獲取到,並且當前線程名如果在線程池配置 的話也會顯示自定義命名

 

 

 比如在開始的AsyncTaskConfig配置文件中在配置線程池時加入前綴:

executor.setThreadNamePrefix("-TaskExecutor-");

 

 在上面可以通過debug看到線程的用戶信息為null,所以需要我們手動往里傳入主線程的信息:

解決辦法:新建公共方法,在調用異步方法之前獲取到userInfo,將userInfo作為參數輸出如異步方法中,異步方法中調用setUserInfo方法

    private static final ThreadLocal<UserInfo> context = new ThreadLocal<UserInfo>();
    
    public void setUserInfo(){
        UserInfo currentThreadUserInfo = SecurityHelper.getUserInfo();
        context.set(currentThreadUserInfo);
    }

在使用完之后,調用clearUserInfo清空信息:

    private static final ThreadLocal<UserInfo> context = new ThreadLocal<UserInfo>();

    public void setUserInfo(){
        UserInfo currentThreadUserInfo = SecurityHelper.getUserInfo();
        context.set(currentThreadUserInfo);
    }

    public void clearUserInfo(){
        context.remove();
    }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM