衆所周知微信公衆號開發時,請求微信服務器需要攜帶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,僅當方法聲明注入的時候,再釋放。