微信開發如何優雅的注入token

衆所周知微信公衆號開發時,請求微信服務器需要攜帶token,如何在業務更好的使用token呢,引出下文(呵呵呵)。

這裏介紹的token是使用readWrite鎖的方式獲取和釋放,沒有用這種方法的業務處理本次不做討論(感覺沒有讀寫鎖,token的使用是不可靠的,詳情請閱讀我的博客‘微信開發-定時獲取token,保證線程安全,高可用’),即處理業務前獲取token並加鎖,處理完畢後又要釋放token並解鎖,非常不方便那麼如何讓人更懶一些(懶惰推動科技進步),程序員只實現業務處理而不去管token的獲取和釋放問題呢?我想到的方法有2種。1:通過代理在方法前後做手腳,2:通過重寫spring相關的參數處理類做手腳。此次先介紹第一種方法,第二種待續。。


首先使用切面是代理的最好選擇,先配置好切面類在,在方法前注入token,方法完畢後釋放token(包括異常情況),先配置一個切面類

@Aspect
@Order(1)
@Component
public class WeChatAspect {

    //聲明切面,使用方法同spring
    @Pointcut("execution(* com.ccx.*.controller..*Controller.*(..))")

    //需要加上
    public void WeChatAspect() { }

    //spring容器工具欄(上篇有介紹到)
    @Autowired
    private SpringContextsUtil springContextsUtil;

    //前置方法
    @Before("WeChatAspect()")
    public void SetTokenBefore(JoinPoint point) {
        Object[] args = point.getArgs();

        if (null != args) {
            for (Object arg : args) {
                //實現思路同controler的參數注入
                //用戶寫什麼參數我們儘可能的爲他注入,這裏注入我們的Token類
                if (arg.getClass().toString().equals(Token.class.toString())) {
                    //如果參數列表聲明的Token類,那麼我們爲他注入
                    arg = springContextsUtil.getBean("token");
                }
            }
            }
    }

    //後置方法
    @AfterReturning("WeChatAspect()")
    public void relaseTokenAfterReturn()  {
        //通過容器獲取Token類
        Token token = springContextsUtil.getBean("token", Token.class);
        token.releaseTokenAndUnlock();
    }

    //異常也要釋放
    @AfterThrowing("WeChatAspect()")
    public void relaseTokenAfterThrowing()  {
        //通過容器獲取Token類
        Token token = springContextsUtil.getBean("token", Token.class);
        token.releaseTokenAndUnlock();
    }
}

切面寫好了再看看Token類,這裏並不是真正的工具類,只是爲了模擬效果寫的,需要其他的東西自己搞定

@Component("token")
public class Token {
    private static String token = "XXXXXXXXXXXXXXXXXXXXXXXX";

    private static  ReentrantReadWriteLock lock = new ReentrantReadWriteLock();

    /*
    * @Description:  獲取token的同時加讀鎖
    * @Author:       hendiaome
    * @CreateDate:   ${DATE} ${TIME}
    * @Param:        v1.0
    * @Return        token
    */
    public String getTokenAndLock() {
        lock.readLock().lock();
        return token;
    }

    /*
    * @Description:  釋放token的同時關閉讀鎖
    * @Author:       hendiaome
    * @CreateDate:   ${DATE} ${TIME}
    * @Param:        v1.0
    * @Return        token
    */
    public void releaseTokenAndUnlock() {
        lock.readLock().unlock();
    }

    public void writeLock() {
        lock.writeLock().lock();;
    }

    public void writeUnLock() {
        lock.writeLock().unlock();;
    }
}

最簡單的就是這樣,最後是controller,也是demo級別的,莫怪。

@Controller
@RequestMapping("/wechat")
public class WeChatController {

    @RequestMapping("/test")
    @ResponseBody
    public Object Test(Token token) {
        String tokenAcess = token.getTokenAndLock();
        //拿着token去做自己的業務處理去吧
        return "OK";
    }

}

好了以上就是簡單的實現了token的自動注入和釋放,應該注意的是在釋放token的時候,應該判讀此方法是否注入了token,,如果沒有聲明token,而後置方法一味的去釋放,是我們不想要的結果,所以應該加入判斷,推薦使用threadlocal,僅當方法聲明注入的時候,再釋放。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章