上文介紹了切面的方法注入token,注意這裏參數聲明的是token類,用String聲明token,切面的before方法無法捕捉(不知爲何),這裏繼續前文,通過增加修改參數綁定類來實現。
Controller的參數綁定於HandlerMethodArgumentResolver負責綁定,我們只需要增加一個處理類,即可處理我們自己定義的參數。首先增加一個處理類
<mvc:annotation-driven>
<mvc:argument-resolvers>
<bean class="com.hendiaome.test.resolver.TokenResolver"></bean>
</mvc:argument-resolvers>
</mvc:annotation-driven>
需要知道resolve是一個集合,處理時調用集合的resolve類來進行參數的支持與否和綁定就ok了。
處理類
public class TokenResolver implements HandlerMethodArgumentResolver{
@Override
public boolean supportsParameter(MethodParameter parameter) {
//此次直接用string接受token
String tokenClass = parameter.getParameterType().getName();
//參數的名字就是token
String tokenParamName = parameter.getParameterName();
if (String.class.getName().equals(tokenClass) && "token".equals(tokenParamName)) {
return true;
}
return false;
}
@Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
//後續爲釋放token做準備,只釋放參數聲明的controller方法
Token.threadLocal.set(true);
return Token.getTokenAndLock();
}
}
controller類更加簡單
@RequestMapping("/test")
@ResponseBody
public String test(String token) {
System.out.println(token);
//拿着token去做自己的業務處理去吧
return "OK";
}
這樣token的獲取加鎖就完成了,頭疼的問題是什麼是否釋放並解鎖,不想再用切面了,想想spring mvc的原理,從dispatcher入手,再分配完處理完請求後執行我們的釋放方法。
<servlet>
<description>spring mvc servlet</description>
<servlet-name>DispatcherServlet</servlet-name>
<servlet-class>com.hendiaome.test.resolver.TokenDispatcher</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:config/spring-mvc.xml
</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
public class TokenDispatcher extends DispatcherServlet {
@Override
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
try {
//執行父類的分配方法
super.doDispatch(request, response);
} catch (Exception e) {
throw e;
} finally {
//完畢後釋放我們的鎖
if (Token.threadLocal.get()) {
Token.releaseTokenAndUnlock();
}
}
}
}
這樣就完成了,感覺還是這種方法好一點,第一篇有一個缺陷(未解決)。參考文獻http://blog.csdn.net/joeyon1985/article/details/49904681