用一个简单的java web实例来说明:
UserSessionFilter.java 过滤器
HttpSession httpsession = ((HttpServletRequest)req).getSession();
private static ThreadLocal<HttpSession> session = new ThreadLocal<HttpSession>();
UserSessionFilter.session.set(httpsession); >>> 本类中的session初始值为HttpSession
Object userSession = httpsession.getAttribute("user"); >>> 从HttpSession中取得"user"的值
ThreadLocalUserSession.set(userSession); >>> 将从HttpSession中取得"user"的值设置到ThreadLocal中
Map<String, Object> map = (Map<String, Object>)session.getAttribute("vars"); 取HttpSession中的"vars"并设置到ThreadLocalUserSession类中
ThreadLocalUserSession.setVars(map);
UserSessionUtil.java 工具类
设置session:
1.
UserSessionFilter.getHttpSession().setAttribute("user", userSession); >>> 本质是往HttpSession中设置
ThreadLocalUserSession.set(userSession); >>> 本质是往ThreadLocal中设置
2.
UserSessionFilter.getHttpSession().setAttribute("vars", vars); >>> 本质是往HttpSession中设置
ThreadLocalUserSession.setVars(vars); >>> 本质是往ThreadLocal中设置
取值session:
ThreadLocal.get(); >>> 本质是从ThreadLocal中取值
====================================
web.xml:
<filter>
<filter-name>UserSessionFilter</filter-name>
<filter-class>com.licaike.framework.server.filter.UserSessionFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>UserSessionFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
UserSessionFilter.java:
public class UserSessionFilter implements Filter{
private static ThreadLocal<HttpSession> session = new ThreadLocal<HttpSession>();
public void destroy() {
}
public static HttpSession getHttpSession(){
return UserSessionFilter.session.get();
}
public void doFilter(ServletRequest req, ServletResponse res, FilterChain filterChain) throws IOException, ServletException {
// 仅仅是记录下WEB session
HttpSession session = ((HttpServletRequest)req).getSession();
UserSessionFilter.session.set(session);
//设置用户身份信息
Object userSession = session.getAttribute("user");
ThreadLocalUserSession.set(userSession);
// 设置session变量
Map<String, Object> map = (Map<String, Object>)session.getAttribute("vars");
if(map == null){
map = new HashMap<String,Object>();
}
ThreadLocalUserSession.setVars(map);
filterChain.doFilter(req, res);
}
public void init(FilterConfig arg0) throws ServletException {
}
}
UserSessionUtil.java:
public class UserSessionUtil {
public static UserSession get(){
return (UserSession)ThreadLocalUserSession.get();
}
//调用此方法真正写入到session
public static void set(UserSession userSession){
UserSessionFilter.getHttpSession().setAttribute("user", userSession); //过滤器里设到本地线程变量里
ThreadLocalUserSession.set(userSession); //此处设到本地线程变量里
}
public static Map<String,Object> getVars(){
return ThreadLocalUserSession.getVars();
}
public static void setVars(Map<String,Object> vars){
UserSessionFilter.getHttpSession().setAttribute("vars", vars); //过滤器里设到本地线程变量里
ThreadLocalUserSession.setVars(vars); //此处设到本地线程变量里
}
public static void initSession(){
//初始化userSession
if(get()==null) set(new UserSession());
//初始化其他
if(getVars()==null) setVars(new HashMap<String,Object>());
}
}
ThreadLocalUserSession.java:
public class ThreadLocalUserSession implements Serializable{
private static ThreadLocal<Object> threadLocalUserSession = new ThreadLocal<Object>() ;
private static ThreadLocal<Map<String,Object>> vars = new ThreadLocal<Map<String,Object>>() ;
public static void set(Object object){
threadLocalUserSession.set(object);
}
public static Object get(){
Object object = threadLocalUserSession.get();
return object;
}
public static void setVars(Map<String,Object> vars){
ThreadLocalUserSession.vars.set(vars);
}
public static Map<String,Object> getVars(){
Map<String,Object> map = vars.get();
return map;
}
private static final long serialVersionUID = 4343534534354L;
}
====================================
关于Theadlocal的说明:
进入Theadlocal代码,可以发现如下的片段:
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();
}
这说明ThreadLocal确实只有一个变量,但是它内部包含一个map,针对每个thread保留一个entry。