1. 程式人生 > >解決 springboot整合shiro,redis快取session 多次從redis獲取session問題

解決 springboot整合shiro,redis快取session 多次從redis獲取session問題

    spring boot整合shiro redis快取session的教程很多,我這裡就不多說了,看了好多教程沒有解決快取session 多次從redis獲取session的問題,所以發表此部落格,希望對大家有所幫助。本人也是小白一個,如果有什麼問題還請各位大神多多指教!

     其實我們在自定義RedisSessionDao的時候 重寫了doReadSession方法 讀取session,我們可以往裡面跟一下看看 其實呼叫的是SessionManager的retrieveSession方法。好了,看到這我們就有大概思路了,我們可以自定義SessionManager,重新retrieveSession方法,把session放到request裡面,這樣就不用每次去redis裡面去取了,這樣大大提高了redis的效能。

    思路有了,咱們一起來看程式碼吧!

import org.apache.shiro.session.Session;
import org.apache.shiro.session.mgt.SessionKey;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.apache.shiro.web.session.mgt.WebSessionKey;
import javax.servlet.ServletRequest;
import java.io.Serializable;

/**
 * @Auther: lianyc
 * @Date: 2018/8/14 15:04
 * @Description:
 */
public class ShiroSessionManager extends DefaultWebSessionManager {

	public ShiroSessionManager(){
		super();
	}


	//重寫這個方法為了減少多次從redis中讀取session(自定義redisSessionDao中的doReadSession方法)
	protected Session retrieveSession(SessionKey sessionKey){
		Serializable sessionId = getSessionId(sessionKey);
		ServletRequest request = null;
		if(sessionKey instanceof WebSessionKey){
			request = ((WebSessionKey)sessionKey).getServletRequest();
		}
		if(request != null && sessionId != null){
			Session session =  (Session) request.getAttribute(sessionId.toString());
			if(session != null){
				return session;
			}
		}
		Session session = super.retrieveSession(sessionKey);
		if(request != null && sessionId != null){
			request.setAttribute(sessionId.toString(),session);
		}
		return session;
	}
}

最後把自定義sessionManager注入到SecurityManager中

@Bean(name="securityManager")
public DefaultWebSecurityManager securityManager() {  
    DefaultWebSecurityManager manager = new DefaultWebSecurityManager();  
    //自定義session管理
    manager.setSessionManager(sessionManager());
    return manager;  
}

好了,這樣就解決了多次從redis獲取session問題。