在@Async注解下RequestContextHolder.getRequestAttributes() 獲得null的情況


我們有的時候會在service層獲取request填充一些諸如用戶名和IP地址等信息,這個時候如果不想從Controller層傳request,可以在service直接使用

HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();

但是,如果service層的函數是異步的話,是獲取不到request的。

通常RequestContextHolder.getRequestAttributes()無法在子線程等異步情況下使用,

如果非要獲取request里的屬性,只能先預置一個函數填充數據后再啟動異步函數。

可以參照:https://stackoverflow.com/questions/51974083/requestcontextholder-getrequestattributes-getting-null-after-async

例如:

public void writeLog(String action,String event)
    {
        //在異步里或者子線程里無法獲取RequestContextHolder.getRequestAttributes()
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        SysLog sysLog = new SysLog();
        sysLog.setAction(action);
        sysLog.setEvent(event);
        sysLog.setHost(NetworkUtils.getIpAddress(request));
        sysLog.setUserName((String)request.getSession().getAttribute("userName"));
        sysLog.setInsertTime(LocalDateTime.now());
        save(sysLog);
    }

    @Async    
    public void save(SysLog sysLog) {

        sysLogRepository.save(sysLog);
    }

 更正一下:

在同一類里writeLog調用save,save並不會進入異步,這個涉及到動態代理的問題,解決辦法是將兩個步驟分開到兩個類里。


免責聲明!

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



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