ThreadLocal原理与应用

最近在维护一个老(很老)系统,本想重构,但是目前没这个时间,基于struts1+dao,有些还是jsp+dao的方式,用户需要在敏感的操作上加比较详细的日志,日志的功能在dao根据需求手动写入,主要的问题是原有的接口没有传入request的相关信息,比如用户信息,我想到了ThreadLocal,因为每个servlet是基于多线程,但是每个request的执行是再一个独立的线程中完成,ThreadLocal正适合了我这种需求,可以用来完成我对这个系统的业务扩展。
在比如struts2的ServletActionContext中对request的获取,还有hibernate中对sessin的管理就是基于ThreadLocal来实现。
看了下ThreadLocal的源码,相对简单,主要的思路是在每个Thread中维护一个ThreadLocalMap,调用ThreadLocal的set(T value)的时候,以当前的ThreadLocal实例为key保存到当前线程的ThreadLocalMap中。

关键源码如下:
public void set(T value) {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null)
map.set(this, value);
else
createMap(t, value);
}
public T get() {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null) {
ThreadLocalMap.Entry e = map.getEntry(this);
if (e != null)
return (T)e.value;
}
return setInitialValue();
}

理解了上面的以后,使用起来就方便了。我的地体实现如在
1.在web.xml中配置系统每个请求都经过的过滤器
<filter>
<filter-name>AppRequestFilter</filter-name>
<filter-class>com.clifford.restaurant.AppRequestFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>AppRequestFilter</filter-name>
<url-pattern>*.jsp</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>AppRequestFilter</filter-name>
<url-pattern>*.do</url-pattern>
</filter-mapping>

2.过滤器实现
public class AppRequestFilter implements Filter{
public void destroy() {
}
public void doFilter(ServletRequest arg0, ServletResponse response,
FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = ((HttpServletRequest)arg0);
RequestThreadLocal.setRequestThreadLocal(request);
filterChain.doFilter(request, response);
}
}


3.ThreadLocal相关实现
public class RequestThreadLocal {
private static ThreadLocal<HttpServletRequest> requestThreadLocal = new ThreadLocal<HttpServletRequest>();
public static void setRequestThreadLocal(HttpServletRequest request) {
requestThreadLocal.set(request);
}
public static User getLoginUser() {
HttpServletRequest request = requestThreadLocal.get();
Session session = request==null?null:request.getSession(false);
return session==null?null:(User)session.getAttribute(IConstants.USER_KEY);
}
public static String getRequestIp() {
HttpServletRequest request = requestThreadLocal.get();
return request==null?"":request.getRemoteHost();
}

}
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值