天天看點

小記:springboot+aop記錄記錄檔,遇到需要異步執行的接口

場景:功能要求管理者可以通過在pc端web頁面通過背景,給連接配接背景的一些裝置設定定時開關。

背景和裝置直接使用tcp保持長連接配接,并使用約定的格式編碼資料,這不是重點。

為了滿足上面的需求,使用了WebAsyncTask進行處理背景與裝置之間的互動,互動完成後,背景再将互動結果回報給前端,告知管理者。

這部分順便貼下關鍵代碼:

@RequestMapping("/")
    public WebAsyncTask<BaseResult> testActionRecord() {

        Callable<BaseResult> callable=new Callable<BaseResult>() {
            @Override
            @ActionRecord(async = true, description = "什麼都不是", action = "/test")
            public BaseResult call() throws Exception {
                System.err.println("test()");
                Test1 test1 = new Test1();
                test1.setAction("11");
                mapper.insertSelective(test1);
                BaseResult baseResult = new BaseResult();
                baseResult.setStatu(Status.STATU_SUCCESS);
                baseResult.setMsg(Status.MSG_SUCCESS);
                return baseResult;
            }
        };
        return new WebAsyncTask<>(callable);
    }
           

上面的代碼直接簡單模拟下了異步任務如何使用,其實為了與背景互動還需要用到回調函數。

tcp端使用mina,每個用戶端有專門的連接配接IoSession,全部通過ip和IoSession的key--value格式儲存到本地Map。

回調函數通過IoSession.setAttribute方法以一個屬性的形式綁定到連接配接IoSession上。在接口處使用thread.wait暫停主線程,然後等tcp那邊處理完畢後調用回調函數通知這邊主線程調用notify喚醒,然後将結果告知客戶。

這也不是重點。

重點是要添加記錄檔,記錄使用者行為,網上一搜一大堆,spring + aop +自定義注解實作。不多說。

上面代碼中@ActionRecord注解就是我自己實作的注解,需要記錄記錄檔的接口方法上隻需要添加這個注解,裡面的屬性也是自定義的。

然而,對于那些失敗的操作,我們是沒必要記錄日志的,是以,在注解業務裡面涉及到了擷取接口傳回狀态的操作,也不難,網上一搜一大堆。

現在碰到了上面這種異步的傳回,如果在注解業務裡面做的話,通過

ProceedingJoinPoint 的 proceed方法,隻能拿到WebAsyncTask這個對象,還要用這個對象去執行 getCallable().call()才能拿到結果。
           

這麼一來,異步任務相當于執行了兩次。

是以,對于這種異步任務要記錄記錄檔,就不能在接口上面加記錄記錄檔的自定義注解了,而是像上面貼出的代碼那樣,寫到call()方法上。

另:上面的自定義屬性async,當時就是為了區分普通接口和異步執行接口的,現在也沒必要留着了。

繼續閱讀