利用threadLocal 把攔截器中的物件傳遞到controller或service中
阿新 • • 發佈:2019-01-24
可以用 request 攜帶資料。
更優雅的方式是用threadlocal
。請求進入tomcat 和產生響應前,都處於同一個執行緒中
比如在一個登入攔截器中,在preHandle
方法中登入成功後,放行前,想把user物件傳到controller或service中
- 建立一個類
UserThreadLocal.java
public class UserThreadLocal {
//把建構函式私有,外面不能new,只能通過下面兩個方法操作
private UserThreadLocal(){
}
private static final ThreadLocal<User> LOCAL = new ThreadLocal<User>();
public static void set(User user){
LOCAL.set(user);;
}
public static User get(){
return LOCAL.get();
}
}
相當於一個容器,此容器伴隨著執行緒,執行緒啟動,就有這個容器,銷燬,容器就跟著銷燬。生命週期就是這個執行緒。
- 在攔截器中,登入成功後,放行前加上
//登入成功
UserThreadLocal.set(user);//將user物件放置在本地執行緒中,方便controller和service獲取
由於tomcat 的執行機制,要及時清空threadLocal的內容
以下可以放在攔截器的afterCompletion方法中
/*tomcat底層 每一個請求都是一個執行緒,如果每一個請求都啟動一個執行緒,效能就會降低,
1. 於是就有了執行緒池,而執行緒池中的執行緒並不是真正銷燬或真正啟動的。
2. 也就是說這個請求的執行緒是個可複用的執行緒,第二次請求可能還會拿到剛剛的執行緒,
3. 若不清空,裡面本身就有user物件,資料會錯亂*/
UserThreadLocal.set(null); //清空本地執行緒中的user物件資料
- 在controller 或 service 中呼叫
User user = UserThreadLocal.get();