记得在一篇博文中看到描述threadLocal的一句话:
ThreadLocal除了适用于多线程保证每条线程都有自己的变量副本外,还适用于在线程上下文中共享某些变量值。
这两种说法是有区别的。前者强调的是,使用ThreadLocal对副本做保护,避免同步、加锁,降低效率;后者强调的是,某个变量线程上下文中,A处用到、B处用到、C处用到,先在入口处set一个值,后使用ThreadLocal的get方法直接在需要用到的地方拿这个值。
项目中,最近理由cookie存值,使用到了threadLocal这个字段,自己就想去研究下,原理这里跟后者强调的一样,上代码:
1.web.xml里边配置过滤器,拦截请求,做处理
<filter>
<filter-name>InterceptorFilter</filter-name>
<filter-class>com.fx.anniversary.core.filter.InterceptorFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>InterceptorFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
2.赋值
public class InterceptorFilter implements Filter{
publicvoiddestroy(){
}
publicvoiddoFilter(ServletRequestrequest,ServletResponseresponse,FilterChainchain)throwsIOException,ServletException{
HttpServletRequesthttpRequest=(HttpServletRequest)request;
HttpServletResponsehttpResponse=(HttpServletResponse)response;
InterceptorContext.setRequest(httpRequest);
InterceptorContext.setResponse(httpResponse);
try{
chain.doFilter(request,
response);
}finally{
//不管有木有出现异常,finally块中代码都会执行;在这里,相当于只服务于当前请求。
InterceptorContext.removeRequest();
InterceptorContext.removeResponse();
}
}
public void init(FilterConfigfilterConfig)throwsServletException{
}
}
3.
InterceptorContext实体
public class InterceptorContext{
private static ThreadLocal<httpservletrequest> _request = newThreadLocal<httpservletrequest>();
private static ThreadLocal<httpservletresponse> _response = newThreadLocal<httpservletresponse>();
publicstaticvoidsetRequest(HttpServletRequestrequest){
_request.set(request);
}
public static HttpServletRequestgetRequest(){
HttpServletRequestrequest=_request.get();returnrequest;
}
public static void removeRequest(){
_request.remove();
}
public static void setResponse(HttpServletResponseresponse){
_response.set(response);
}
public static HttpServletResponsegetResponse(){
HttpServletResponseresponse=_response.get();
return response;
}
public static void removeResponse(){
_response.remove();
}
}
4.项目中的开始调用。(因为这两个方法调用的地方太多,每次都带一个参数也比较繁琐,所以采用这种方式,文章开头总结过)
public String getAttribute(Stringkey){
HttpServletRequestrequest = InterceptorContext.getRequest();
Cookie[]cookies=request.getCookies();
if(cookies!=null){
for(Cookie cookie: cookies){
if(cookie.getName().equals(key)){
return cookie.getValue();
}
}
}
return"";
}
@Override
public void setAttribute(String key,String value){
HttpServletResponse response=InterceptorContext.getResponse();
Cookiecookie=newCookie(key,value);
response.addCookie(cookie);
}