shiro 减少用redis实现的自定义SessionDAO的doUpdate的调用次数

来源:互联网 发布:淘宝十大人气主播 编辑:程序博客网 时间:2024/06/05 13:07

由于SimpleSession lastAccessTime更改后也会调用SessionDao update方法,更新的字段只有LastAccessTime(最后一次访问时间),由于会话失效是由Redis数据过期实现的,这个字段意义不大,为了减少对Redis的访问,降低网络压力,实现自己的Session,在SimpleSession上套一层,增加一个标识位,如果Session除lastAccessTime意外其它字段修改,就标识一下,只有标识为修改的才可以通过doUpdate访问Redis,否则直接返回。


import org.apache.shiro.session.mgt.SimpleSession;    import java.io.Serializable;  import java.util.Date;  import java.util.Map;      /**  * 由于SimpleSession lastAccessTime更改后也会调用SessionDao update方法,  * 增加标识位,如果只是更新lastAccessTime SessionDao update方法直接返回  */  public class ShiroSession extends SimpleSession implements Serializable {      // 除lastAccessTime以外其他字段发生改变时为true      private boolean isChanged;        public ShiroSession() {          super();          this.setChanged(true);      }        public ShiroSession(String host) {          super(host);          this.setChanged(true);      }          @Override      public void setId(Serializable id) {          super.setId(id);          this.setChanged(true);      }        @Override      public void setStopTimestamp(Date stopTimestamp) {          super.setStopTimestamp(stopTimestamp);          this.setChanged(true);      }        @Override      public void setExpired(boolean expired) {          super.setExpired(expired);          this.setChanged(true);      }        @Override      public void setTimeout(long timeout) {          super.setTimeout(timeout);          this.setChanged(true);      }        @Override      public void setHost(String host) {          super.setHost(host);          this.setChanged(true);      }        @Override      public void setAttributes(Map<Object, Object> attributes) {          super.setAttributes(attributes);          this.setChanged(true);      }        @Override      public void setAttribute(Object key, Object value) {          super.setAttribute(key, value);          this.setChanged(true);      }        @Override      public Object removeAttribute(Object key) {          this.setChanged(true);          return super.removeAttribute(key);      }        /**      * 停止      */      @Override      public void stop() {          super.stop();          this.setChanged(true);      }        /**      * 设置过期      */      @Override      protected void expire() {          this.stop();          this.setExpired(true);      }        public boolean isChanged() {          return isChanged;      }        public void setChanged(boolean isChanged) {          this.isChanged = isChanged;      }        @Override      public boolean equals(Object obj) {          return super.equals(obj);      }        @Override      protected boolean onEquals(SimpleSession ss) {          return super.onEquals(ss);      }        @Override      public int hashCode() {          return super.hashCode();      }        @Override      public String toString() {          return super.toString();      }  }  


import org.apache.commons.lang3.StringUtils;  import org.apache.shiro.session.Session;  import org.apache.shiro.session.mgt.SessionContext;  import org.apache.shiro.session.mgt.SessionFactory;  import org.apache.shiro.web.session.mgt.DefaultWebSessionContext;  import org.slf4j.Logger;  import org.slf4j.LoggerFactory;    import javax.servlet.http.HttpServletRequest;    public class ShiroSessionFactory implements SessionFactory {      private static final Logger logger = LoggerFactory.getLogger(ShiroSessionFactory.class);        @Override      public Session createSession(SessionContext initData) {          ShiroSession session = new ShiroSession();          HttpServletRequest request = (HttpServletRequest)initData.get(DefaultWebSessionContext.class.getName() + ".SERVLET_REQUEST");          session.setHost(getIpAddress(request));          return session;      }        public static String getIpAddress(HttpServletRequest request) {          String localIP = "127.0.0.1";          String ip = request.getHeader("x-forwarded-for");          if (StringUtils.isBlank(ip) || (ip.equalsIgnoreCase(localIP)) || "unknown".equalsIgnoreCase(ip)) {              ip = request.getHeader("Proxy-Client-IP");          }          if (StringUtils.isBlank(ip) || (ip.equalsIgnoreCase(localIP)) || "unknown".equalsIgnoreCase(ip)) {              ip = request.getHeader("WL-Proxy-Client-IP");          }          if (StringUtils.isBlank(ip) || (ip.equalsIgnoreCase(localIP)) || "unknown".equalsIgnoreCase(ip)) {              ip = request.getRemoteAddr();          }          return ip;      }  }  


在自定义的RedisDAO中的做判断

    /**      * 更新会话;如更新会话最后访问时间/停止会话/设置超时时间/设置移除属性等会调用      */      @Override      protected void doUpdate(Session session) {          //如果会话过期/停止 没必要再更新了          try {              if (session instanceof ValidatingSession && !((ValidatingSession) session).isValid()) {                  return;              }              if (session instanceof ShiroSession) {                  // 如果没有主要字段(除lastAccessTime以外其他字段)发生改变                  ShiroSession ss = (ShiroSession) session;                  if (!ss.isChanged()) {                      return;                  }                  //更新redis                ......        } catch (Exception e) {              logger.warn("更新Session失败", e);          }       }  


原创粉丝点击