tomcat 创建session的核心代码解刨

自己写的controller类:
@Controller
public class UserController {
         @Autowired
         UserService userService;
         @RequestMapping("/index.action")
         @ResponseBody
         public String index(HttpServletRequest req ,String name){
             HttpSession session = req.getSession(true);//从这里开始解剖session,调用了RequestFacade类:getSession(boolean create)
             String id = session.getId();
             System.out.println("id : "+id);
             Cookie[] cookies = req.getCookies(); //调用了RequestFacade类:getSession(boolean create)
//             for(Cookie c :cookies){
//                 System.out.println(c.getValue());
//             }
             
             System.out.println(" /index.action  name:  "+name);
             return "index";
         }
    }
RequestFacade类:
 public HttpSession getSession(boolean create)
    {
        if(request == null)
            throw new IllegalStateException(sm.getString("requestFacade.nullRequest"));
        if(SecurityUtil.isPackageProtectionEnabled())
            return (HttpSession)AccessController.doPrivileged(new GetSessionPrivilegedAction(create));
        else
            // 调用Request类:getSession(boolean create),request为RequestFacade类的成员变量类型为Request类
            return request.getSession(create);
    }
Request类:
 public HttpSession getSession(boolean create)
    {
        Session session = doGetSession(create); //这里开始创建session
        if(session != null)
            return session.getSession();
        else
            return null;
    }
protected Session doGetSession(boolean create)
    {
        if(context == null)
            return null;
        if(session != null && !session.isValid())
            session = null;
        if(session != null)
            return session;
        Manager manager = null;
        if(context != null)
            manager = context.getManager();
        if(manager == null)
            return null;
        if(requestedSessionId != null)
        {
            try
            {
                session = manager.findSession(requestedSessionId);//现根据sessionId 查询,如果没有则创建
         
  }
            catch(IOException e)
            {
                session = null;
            }
            if(session != null && !session.isValid())
                session = null;
            if(session != null)
            {
                session.access();
                return session;
            }
        }
        if(!create)
            return null;
        if(context != null && response != null && context.getCookies() && response.getResponse().isCommitted())
            throw new IllegalStateException(sm.getString("coyoteRequest.sessionCreateCommitted"));
        if(connector.getEmptySessionPath() && isRequestedSessionIdFromCookie())

           //根据请求中sessionID创建session,调用ManagerBase类:createSession(String sessionId)
            session = manager.createSession(getRequestedSessionId());
        else

            //调用ManagerBase类:createSession(String sessionId)
            session = manager.createSession(null); //这里是自动生成sessionID(往下看),并创建session


            //创建session完成后,根据已经生成的或已有的sessionId创建cookie,并且把cookie加入response中反应给前台
        if(session != null && getContext() != null && getContext().getCookies())
        {
            String scName = context.getSessionCookieName();
            if(scName == null)
                scName = Globals.SESSION_COOKIE_NAME;  //拿取cookie的名字,可以自己配置,(如果没有配置cookie的名字则使用默认)
            Cookie cookie = new Cookie(scName, session.getIdInternal()); //根据cookieName 和 sessionID 创建一个cookie
            configureSessionCookie(cookie); //设置cookie的一些属性                         
            response.addSessionCookieInternal(cookie, context.getUseHttpOnly());//将cookie设置到response中
        }
        if(session != null)
        {
            session.access(); 
            return session;   //返回创建的session
        } else
        {
            return null;
        }
    }
    //设置cookie的一些属性
    // cookie的发送限制是由 domain+path  进行限制的,解决客户端访问不同的服务器,传递对应的cookie

     protected void configureSessionCookie(Cookie cookie)
    {
        cookie.setMaxAge(-1);  //设置永远不过时
        Context ctxt = getContext();
        String contextPath = null;
        if(ctxt != null && !getConnector().getEmptySessionPath())
            if(ctxt.getSessionCookiePath() != null)
                contextPath = ctxt.getSessionCookiePath();
            else
                contextPath = ctxt.getEncodedPath();
        //设置在客户端保存cookie的路径        
        if(contextPath != null && contextPath.length() > 0)
            cookie.setPath(contextPath); //设置cookie的保存路径path(如果手动配置的话)
        else
            cookie.setPath("/"); //设置cookie的保存路径path,默认为根目录 / 
        if(ctxt != null && ctxt.getSessionCookieDomain() != null)
        //设置域名domain,默认为 当前请求的域名,手动设置的时候必须以 . 开头 否者无效
        //同时也暗示只能是子域名

            cookie.setDomain(ctxt.getSessionCookieDomain()); 
        if(isSecure())
            cookie.setSecure(true);   //设置安全模式
    }
    

ManagerBase类:
 public Session createSession(String sessionId)
    {
        Session session = createEmptySession();
        session.setNew(true); //设置为新的创建
        session.setValid(true); //设置是有效的
        session.setCreationTime(System.currentTimeMillis());//设置创建的时间
        //60:为秒,设置存活时间默认 sessionTimeout = 30; 30分钟 
        session.setMaxInactiveInterval(((Context)getContainer()).getSessionTimeout() * 60); 
        if(sessionId == null)
            //生成sessionId,永远不会重复,因为生成的时候会:sessions.containsKey(result)
            // 如果发现sessions 的key中存在了sessionID  则会重新生成,直到不存在返回生成的 sessionID

            sessionId = generateSessionId(); 
        //给当的session设置sessionId并 保存当前新创建的session对象到 Map sessions 中,sessionId 作为key,session 作为v
        //保存的逻辑请看 调用了 ManagerBase类:
add(Session session) 方法
        session.setId(sessionId);
        sessionCounter++;
        SessionTiming timing = new SessionTiming(session.getCreationTime(), 0);
        synchronized(sessionCreationTiming)
        {
            sessionCreationTiming.add(timing);
            sessionCreationTiming.poll();
        }
        return session;
    }
     //将session放入容器中
     public void add(Session session)
    {
        sessions.put(session.getIdInternal(), session); //将session放入到 Map sessions 中
        int size = sessions.size();
        if(size > maxActive)
            synchronized(maxActiveUpdateLock)
            {
                if(size > maxActive)
                    maxActive = size;
            }
    }
 
 解剖tomcat 创建session的源码就到这里吧。
 

猜你喜欢

转载自blog.csdn.net/qq_29499107/article/details/83388197