我有以下课程:
public class AppContext {
private static final ThreadLocal<AppContextData> contextHolder = new ThreadLocal<AppContextData>() {
@Override
protected AppContextData initialValue() {
return new AppContextData();
}
};
public static AppContextData get() {
return contextHolder.get();
}
public static void unset() {
contextHolder.remove();
}
}
public class AppContextData {
//many getter and setter methods
}
网站开始在拦截器中使用ThreadLocal对象,该对象用于完成Web请求。
public class MyIntercepter extends HandlerInterceptorAdapter {
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
AppContext.get();
//.....
}
}
我在Tomcat 8.x上运行此网站,我发现该日志有以下错误消息。
如何解决此问题?
非常感谢任何意见!
20-May-2016 22:43:53.657 SEVERE [localhost-startStop-2] org.apache.catalina.loader.WebappClassLoaderBase.checkThreadLocalMapForLeaks Web应用程序[ROOT]创建了一个类型为[my.organization]的密钥的ThreadLocal。 data.AppContext $ 1](值[my.organization.data.AppContext$1@31d4463a])和类型[my.organization.data.AppContextData]的值(值[my.organization.data.AppContextData@e89d5f4])但失败在Web应用程序停止时删除它。线程将随着时间的推移而更新,以避免可能的内存泄漏。
答案 0 :(得分:1)
JanPi已经在评论中说我们要做什么。如果有人想知道如何,这里是:
public class MyIntercepter extends HandlerInterceptorAdapter {
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
AppContext.get();
//.....
}
public void afterCompletion(
HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
AppContext.unset();
}
public void afterConcurrentHandlingStarted(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception{
// only relevant when a handler starts an asynchronous request.
AppContext.unset();
}
}
postHandle方法看起来是一个好地方,但afterCompletion更好,因为即使处理程序无法正确处理请求(也就是发生异常),它也会被调用。