HttpSessionBindingListener 的用法筆記250417

HttpSessionBindingListener 的用法筆記250417

在這里插入圖片描述

HttpSessionBindingListener 是 Java Servlet 規范中 唯一被存儲對象自身實現 的會話監聽接口,


1. 核心功能

HttpSessionBindingListener 是一個由 會話屬性對象自身實現 的接口,用于監聽該對象被綁定到會話(setAttribute)或從會話中移除(removeAttribute)的事件。
HttpSessionAttributeListener(監聽所有屬性變化)不同,此接口由屬性對象自主管理,無需額外注冊監聽器。


2. 核心方法

  • valueBound(HttpSessionBindingEvent event)
    當對象被綁定到會話時觸發(如 session.setAttribute("key", this))。

  • valueUnbound(HttpSessionBindingEvent event)
    當對象從會話中解除綁定時觸發(如 session.removeAttribute("key") 或會話失效)。


3. 實現步驟

步驟 1:創建實現類
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener;public class UserSessionTracker implements HttpSessionBindingListener {private String username;public UserSessionTracker(String username) {this.username = username;}@Overridepublic void valueBound(HttpSessionBindingEvent event) {System.out.printf("用戶 %s 的會話已綁定 | SessionID: %s\n", username, event.getSession().getId());// 初始化資源(如連接會話數據庫)}@Overridepublic void valueUnbound(HttpSessionBindingEvent event) {System.out.printf("用戶 %s 的會話已解除綁定 | 原因: %s\n", username, getUnbindReason(event));// 釋放資源(如關閉臨時文件句柄)}// 輔助方法:判斷解綁原因(主動移除、會話失效等)private String getUnbindReason(HttpSessionBindingEvent event) {if (event.getSession().isNew()) {return "會話已失效(超時或主動銷毀)";} else {return "屬性被主動移除";}}
}
步驟 2:將對象綁定到會話

在業務邏輯(如登錄成功時)將會話感知對象加入會話:

HttpSession session = request.getSession();
UserSessionTracker userTracker = new UserSessionTracker("Alice");
session.setAttribute("currentUser", userTracker); // 觸發 valueBound()

4. 典型應用場景

(1) 資源生命周期管理
public class FileUploadProgress implements HttpSessionBindingListener {private TemporaryFile tempFile;@Overridepublic void valueBound(HttpSessionBindingEvent event) {tempFile = createTempFile(); // 綁定會話時創建臨時文件}@Overridepublic void valueUnbound(HttpSessionBindingEvent event) {if (tempFile != null) {tempFile.delete(); // 解綁時自動清理臨時文件}}
}
(2) 在線用戶狀態同步
public class OnlineUser implements HttpSessionBindingListener {@Overridepublic void valueBound(HttpSessionBindingEvent event) {OnlineUserManager.addUser(this); // 加入在線列表}@Overridepublic void valueUnbound(HttpSessionBindingEvent event) {OnlineUserManager.removeUser(this); // 從在線列表移除}
}
(3) 會話綁定次數統計
public class SessionAwareCounter implements HttpSessionBindingListener {private int bindCount = 0;@Overridepublic void valueBound(HttpSessionBindingEvent event) {bindCount++;System.out.println("對象第 " + bindCount + " 次被綁定到會話");}@Overridepublic void valueUnbound(HttpSessionBindingEvent event) {// 解綁時不減少計數,僅記錄}
}

5. 注意事項

(1) 觸發條件
  • valueBound:僅在對象通過 setAttribute 首次綁定到會話 時觸發。若替換已有屬性(同 key),原對象的 valueUnbound 會先觸發,新對象的 valueBound 隨后觸發。
  • valueUnbound:在以下情況觸發:
    • 顯式調用 removeAttribute("key")
    • 會話超時或調用 invalidate()
    • 服務器關閉(正常關閉時)。
(2) 線程安全
  • 單會話單線程:同一會話的請求通常由同一線程處理,但不同會話可能并發觸發監聽器。若監聽器操作共享資源(如全局計數器),需使用同步機制。
(3) 序列化與集群
  • 分布式會話:若會話被序列化(鈍化),對象需實現 Serializable。注意 valueBoundvalueUnbound 在反序列化(激活)時 不會自動觸發,需依賴容器實現或手動處理。
(4) 避免遞歸調用
  • valueBoundvalueUnbound 中修改當前會話屬性可能導致循環觸發:
    // 錯誤示例:在 valueBound 中再次綁定自身
    public void valueBound(HttpSessionBindingEvent event) {event.getSession().setAttribute("key", this); // 導致無限遞歸
    }
    
(5) 與 HttpSessionAttributeListener 的區別
特性HttpSessionBindingListenerHttpSessionAttributeListener
實現位置屬性對象自身獨立的監聽器類
監聽范圍僅監聽實現該接口的對象監聽所有會話屬性變化
注冊方式無需注冊,自動生效需通過 web.xml@WebListener 注冊
適用場景對象自主管理生命周期全局監控會話屬性變化

6. 最佳實踐

  • 資源自動釋放:在 valueUnbound 中確保釋放對象占用的資源(如文件、網絡連接)。
  • 狀態一致性:在分布式環境中,結合 HttpSessionActivationListener 處理會話鈍化/激活時的狀態恢復。
  • 日志跟蹤:記錄關鍵對象的綁定/解綁事件,輔助調試會話管理問題。
    @Override
    public void valueUnbound(HttpSessionBindingEvent event) {logger.info("對象解綁: " + this + " | 會話ID: " + event.getSession().getId());
    }
    

總結

HttpSessionBindingListener 為特定對象提供了直接感知自身在會話中綁定狀態的機制,適用于資源生命周期管理、狀態同步及精細化監控。重點在于合理實現 valueBoundvalueUnbound 邏輯、避免遞歸陷阱,并在分布式環境中妥善處理序列化與反序列化。結合其他會話監聽器,可構建靈活高效的會話管理體系。










1?? 參考 1

HttpSessionBindingListener 是 Java Servlet 規范中一個特殊的監聽器接口,由存儲在 HTTP 會話(HttpSession)中的對象自身實現。當對象被綁定到會話(通過 setAttribute)或從會話中解綁(通過 removeAttribute 或會話失效)時,會自動觸發其生命周期方法。以下是其核心用法、示例及典型場景:


核心用法步驟

1. 對象實現 HttpSessionBindingListener 接口
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener;public class User implements HttpSessionBindingListener {private String username;public User(String username) {this.username = username;}@Overridepublic void valueBound(HttpSessionBindingEvent event) {// 對象被綁定到會話時觸發(如 session.setAttribute("user", this))System.out.println("用戶綁定到會話: " + username);}@Overridepublic void valueUnbound(HttpSessionBindingEvent event) {// 對象從會話中解綁時觸發(如 session.removeAttribute("user") 或會話失效)System.out.println("用戶從會話解綁: " + username);}
}
2. 將對象存入會話
// 在 Servlet 或 Controller 中
User user = new User("Alice");
request.getSession().setAttribute("user", user); // 觸發 valueBound()

典型應用場景

1. 資源自動管理
public class NetworkConnection implements HttpSessionBindingListener {private Connection conn;@Overridepublic void valueBound(HttpSessionBindingEvent event) {// 綁定到會話時初始化資源conn = DriverManager.getConnection("jdbc:mysql://localhost/db");System.out.println("數據庫連接已建立");}@Overridepublic void valueUnbound(HttpSessionBindingEvent event) {// 解綁時釋放資源if (conn != null) conn.close();System.out.println("數據庫連接已關閉");}
}
2. 用戶在線狀態跟蹤
public class LoginStatus implements HttpSessionBindingListener {private String userId;public LoginStatus(String userId) {this.userId = userId;}@Overridepublic void valueBound(HttpSessionBindingEvent event) {// 用戶登錄時標記為在線OnlineUserManager.markOnline(userId);}@Overridepublic void valueUnbound(HttpSessionBindingEvent event) {// 用戶登出或會話超時后標記為離線OnlineUserManager.markOffline(userId);}
}
3. 會話級緩存清理
public class CachedData implements HttpSessionBindingListener {@Overridepublic void valueUnbound(HttpSessionBindingEvent event) {// 會話失效時清理緩存CacheManager.remove(event.getSession().getId());}
}

注意事項

  1. 無需注冊監聽器
    HttpSessionBindingListener 由對象自身實現,無需在 web.xml 或通過注解配置。

  2. 觸發條件

    • valueBound():當對象通過 setAttribute 存入會話時觸發。
    • valueUnbound():當對象通過 removeAttribute 移除、會話超時或顯式調用 session.invalidate() 時觸發。
  3. 多次綁定的處理
    若同一對象被多次存入會話(不同屬性名),每次 setAttribute 都會觸發 valueBound()。例如:

    session.setAttribute("user1", user); // 觸發 valueBound()
    session.setAttribute("user2", user); // 再次觸發 valueBound()
    
  4. 線程安全
    每個會話在獨立線程中處理,但若對象被多線程共享(如集群環境),需確保其線程安全性。

  5. 避免遞歸調用
    valueBound()valueUnbound() 中修改會話屬性可能導致無限遞歸:

    public void valueBound(HttpSessionBindingEvent event) {event.getSession().setAttribute("key", this); // 危險!
    }
    

HttpSessionAttributeListener 的區別

監聽器實現方式觸發范圍典型用途
HttpSessionBindingListener由會話中的對象實現僅監聽該對象自身資源管理、狀態跟蹤
HttpSessionAttributeListener獨立監聽器類監聽所有會話屬性全局日志、統一業務邏輯

總結

HttpSessionBindingListener 適用于對象級會話生命周期管理,通過將監聽邏輯內聚到對象自身,實現資源自動初始化和清理。其核心優勢在于無需外部配置,但需注意避免遞歸調用和線程安全問題。常見于會話級資源管理、用戶狀態跟蹤等場景。










2?? 參考 2

HttpSessionBindingListener 是 Java Web 開發中用于監聽 對象與會話綁定關系變化 的接口。它允許對象感知自己何時被綁定到用戶會話(Session),以及何時從會話中解除綁定。以下是其核心用法:

一、核心作用

  1. 綁定時:當對象通過 session.setAttribute() 被添加到會話時觸發。
  2. 解除綁定時:當對象通過 session.removeAttribute() 被移除,或會話失效(超時/手動銷毀)時觸發。

二、實現步驟

1. 創建可綁定對象

讓對象實現 javax.servlet.http.HttpSessionBindingListener 接口:

import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener;public class UserSessionData implements HttpSessionBindingListener {private String username;private DatabaseConnection dbConn; // 假設需要管理數據庫連接public UserSessionData(String username) {this.username = username;}// 綁定到會話時調用@Overridepublic void valueBound(HttpSessionBindingEvent event) {System.out.println("對象綁定到會話: " + event.getName());dbConn = createDatabaseConnection(); // 初始化資源}// 從會話解除綁定時調用@Overridepublic void valueUnbound(HttpSessionBindingEvent event) {System.out.println("對象從會話解除綁定: " + event.getName());dbConn.close(); // 釋放資源}private DatabaseConnection createDatabaseConnection() {// 初始化數據庫連接邏輯return new DatabaseConnection();}
}
2. 綁定對象到會話

在 Servlet 或 Controller 中將對象存入會話:

// 在用戶登錄時創建對象并綁定到會話
UserSessionData userData = new UserSessionData("Alice");
request.getSession().setAttribute("userSession", userData);

三、典型應用場景

  1. 資源生命周期管理
    public void valueBound(HttpSessionBindingEvent event) {initExpensiveResource(); // 初始化耗時資源
    }public void valueUnbound(HttpSessionBindingEvent event) {releaseExpensiveResource(); // 釋放資源
    }
    
  2. 會話級緩存管理
    public void valueUnbound(HttpSessionBindingEvent event) {cacheManager.removeUserCache(username); // 清除用戶緩存
    }
    
  3. 統計在線用戶
    public class ActiveUser implements HttpSessionBindingListener {static AtomicInteger activeUsers = new AtomicInteger(0);public void valueBound(HttpSessionBindingEvent event) {activeUsers.incrementAndGet();}public void valueUnbound(HttpSessionBindingEvent event) {activeUsers.decrementAndGet();}
    }
    

四、注意事項

  1. 作用域限制:對象僅在當前會話有效,不同會話中的同名對象獨立。
  2. 避免死循環:不要在 valueBound/valueUnbound 中直接操作會話屬性(如再次調用 setAttribute()),否則會觸發遞歸監聽。
  3. 異常處理:確保 valueUnbound 中的代碼不拋出異常,否則可能影響會話銷毀流程。

五、與 HttpSessionAttributeListener 的區別

監聽器類型監聽主體觸發時機
HttpSessionBindingListener對象自身對象與會話綁定/解除綁定時
HttpSessionAttributeListener會話屬性變化會話屬性增刪改時(不限對象)

通過 HttpSessionBindingListener,可以實現對象級別的會話生命周期管理,適用于需要精細控制資源初始化和釋放的場景,如數據庫連接池、緩存管理、會話級統計等。










3?? 參考 3

以下是 HttpSessionBindingListener 的詳細用法說明,結合知識庫中的信息和實際應用場景:


1. 核心方法

HttpSessionBindingListener 是 Java Web 開發中用于監聽 對象與 HttpSession 綁定或解綁的接口,主要在以下操作時觸發回調方法:

  • valueBound(HttpSessionBindingEvent event)
    當對象被綁定到 HttpSession(即通過 session.setAttribute() 添加到會話中)時調用。
  • valueUnbound(HttpSessionBindingEvent event)
    當對象從 HttpSession 中解綁(即通過 session.removeAttribute() 移除,或會話超時/銷毀時)時調用。

2. 實現步驟

步驟 1:創建監聽器類

實現 HttpSessionBindingListener 接口,并重寫上述方法。通常需要將該監聽器實現到業務對象(如用戶對象)中。

import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener;public class User implements HttpSessionBindingListener {private String username;public User(String username) {this.username = username;}// 當對象被綁定到Session時觸發@Overridepublic void valueBound(HttpSessionBindingEvent event) {System.out.println("用戶 [" + username + "] 被綁定到會話");// 可執行初始化操作,如在線人數統計incrementOnlineCount();}// 當對象從Session中解綁時觸發@Overridepublic void valueUnbound(HttpSessionBindingEvent event) {System.out.println("用戶 [" + username + "] 從會話中解綁");// 可執行清理操作,如減少在線人數decrementOnlineCount();}// 輔助方法:操作在線人數計數器(需線程安全)private void incrementOnlineCount() {// 使用ServletContext存儲全局計數器int count = (int) event.getSession().getServletContext().getAttribute("onlineCount");event.getSession().getServletContext().setAttribute("onlineCount", count + 1);}private void decrementOnlineCount() {int count = (int) event.getSession().getServletContext().getAttribute("onlineCount");event.getSession().getServletContext().setAttribute("onlineCount", count - 1);}
}
步驟 2:將對象綁定到 Session

在需要監聽的對象(如用戶登錄時)將其放入 HttpSession

// 在Servlet或控制器中
HttpSession session = request.getSession();
User user = new User("張三");
session.setAttribute("currentUser", user);  // 觸發valueBound()

3. 典型應用場景

場景 1:在線人數統計

通過監聽用戶對象的綁定和解綁,實時統計在線人數(參考知識庫 [1][4]):

// 在Web應用啟動時初始化計數器
public class MyServletContextListener implements ServletContextListener {@Overridepublic void contextInitialized(ServletContextEvent event) {event.getServletContext().setAttribute("onlineCount", 0);}
}// User類中的valueBound和valueUnbound方法已實現計數邏輯
場景 2:資源釋放

在對象從會話中解綁時釋放資源(如數據庫連接、文件流):

public class ResourceBean implements HttpSessionBindingListener {private Connection connection;@Overridepublic void valueUnbound(HttpSessionBindingEvent event) {if (connection != null) {try {connection.close();} catch (SQLException e) {e.printStackTrace();}}}
}
場景 3:單點登錄(SSO)

確保同一用戶只能在一個設備登錄(參考知識庫 [3][4]):

public class User implements HttpSessionBindingListener {// ...@Overridepublic void valueBound(HttpSessionBindingEvent event) {// 檢查是否已有其他會話登錄該用戶ConcurrentHashMap<String, HttpSession> userSessions = (ConcurrentHashMap<String, HttpSession>) event.getSession().getServletContext().getAttribute("userSessions");if (userSessions.containsKey(this.username)) {// 強制下線舊會話HttpSession oldSession = userSessions.remove(this.username);oldSession.invalidate();}userSessions.put(this.username, event.getSession());}@Overridepublic void valueUnbound(HttpSessionBindingEvent event) {ConcurrentHashMap<String, HttpSession> userSessions = (ConcurrentHashMap<String, HttpSession>) event.getSession().getServletContext().getAttribute("userSessions");userSessions.remove(this.username);}
}

4. 生命周期說明

  • 觸發條件
    • valueBound:調用 session.setAttribute(name, this) 時(對象自身被放入會話中)。
    • valueUnbound:以下情況觸發:
      1. 調用 session.removeAttribute(name)
      2. 會話超時(默認30分鐘)。
      3. 調用 session.invalidate() 顯式銷毀會話。
  • 事件對象 HttpSessionBindingEvent
    • getSession():獲取關聯的 HttpSession
    • getName():獲取綁定到會話中的屬性名。
    • getValue():獲取對象自身的引用(即 this)。

5. 注意事項

  1. 無需注冊監聽器
    • HttpSessionBindingListener 無需在 web.xml 或通過注解注冊。只需在對象實現接口后,將其放入 HttpSession 中即可生效。
  2. 線程安全
    • valueBoundvalueUnbound 中操作共享資源(如計數器)時,需使用線程安全的集合(如 ConcurrentHashMap)或同步機制。
  3. HttpSessionListener 的區別
    • HttpSessionListener:監聽 整個會話的創建和銷毀(如用戶登錄/退出)。
    • HttpSessionBindingListener:監聽 特定對象與會話的綁定關系(對象是否被添加/移除)。
  4. 鈍化/激活監聽
    • 若需監聽會話的鈍化(序列化存儲)和激活(反序列化恢復),需實現 HttpSessionActivationListener

6. 完整示例

示例 1:在線人數統計
// 1. 用戶類實現監聽器
public class User implements HttpSessionBindingListener {private String username;public User(String username) {this.username = username;}@Overridepublic void valueBound(HttpSessionBindingEvent event) {ServletContext context = event.getSession().getServletContext();int count = (int) context.getAttribute("onlineCount");context.setAttribute("onlineCount", count + 1);}@Overridepublic void valueUnbound(HttpSessionBindingEvent event) {ServletContext context = event.getSession().getServletContext();int count = (int) context.getAttribute("onlineCount");context.setAttribute("onlineCount", count - 1);}
}// 2. 初始化計數器(ServletContextListener)
@WebListener
public class AppInitializer implements ServletContextListener {@Overridepublic void contextInitialized(ServletContextEvent event) {event.getServletContext().setAttribute("onlineCount", 0);}
}// 3. 在Servlet中使用
@WebServlet("/login")
public class LoginServlet extends HttpServlet {protected void doPost(HttpServletRequest req, HttpServletResponse resp) {User user = new User("張三");req.getSession().setAttribute("user", user);  // 觸發valueBound()}
}
示例 2:資源釋放
public class DatabaseConnection implements HttpSessionBindingListener {private Connection connection;public DatabaseConnection() {connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb", "user", "password");}@Overridepublic void valueUnbound(HttpSessionBindingEvent event) {try {connection.close();} catch (SQLException e) {e.printStackTrace();}}
}// 在Servlet中使用
@WebServlet("/connect")
public class ConnectServlet extends HttpServlet {protected void doGet(HttpServletRequest req, HttpServletResponse resp) {DatabaseConnection conn = new DatabaseConnection();req.getSession().setAttribute("dbConnection", conn);  // 使用后自動釋放}
}

7. 常見問題解答

Q1:valueUnbound 什么時候不會被觸發?
  • 可能原因:如果會話未被銷毀或對象未被移除(如未調用 removeAttributeinvalidate)。
  • 解決:確保會話超時配置正確,或顯式銷毀會話。
Q2:如何獲取綁定的屬性名?
  • 方法:通過 event.getName() 獲取,例如在 valueBound 中記錄屬性名。
Q3:如何處理多個監聽器對象?
  • 方法:每個監聽器對象獨立,需在各自的方法中處理自身邏輯,避免共享狀態。

總結

HttpSessionBindingListener 是實現 對象級會話綁定監聽 的核心工具,適用于需要精確控制對象與會話關系的場景,如在線人數統計、資源管理和單點登錄。通過在對象中實現接口并綁定到會話,可以自動觸發關鍵操作,確保系統行為符合預期。










4?? 參考 4

HttpSessionBindingListener 是 Java Servlet 規范中的一個接口,它允許對象自身感知其何時被綁定到 HttpSession 以及何時從 HttpSession 中解綁。與其他 HttpSession 相關監聽器不同,HttpSessionBindingListener 不是配置在外部類上,而是由要存儲在會話中的對象類來實現。下面詳細介紹其用法:

用法步驟

  1. 實現 HttpSessionBindingListener 接口:讓要存儲在 HttpSession 中的類實現該接口,并實現 valueBoundvalueUnbound 方法。
  2. valueBound 方法中編寫對象綁定到會話時的邏輯
  3. valueUnbound 方法中編寫對象從會話中解綁時的邏輯
  4. 將對象存儲到 HttpSession 中觸發綁定和解綁事件

示例代碼

以下是一個使用 HttpSessionBindingListener 的示例:

import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener;// 實現 HttpSessionBindingListener 接口的類
public class User implements HttpSessionBindingListener {private String name;public User(String name) {this.name = name;}public String getName() {return name;}// 當對象被綁定到 HttpSession 時調用@Overridepublic void valueBound(HttpSessionBindingEvent event) {System.out.println(name + " 已綁定到會話,會話 ID: " + event.getSession().getId());}// 當對象從 HttpSession 中解綁時調用@Overridepublic void valueUnbound(HttpSessionBindingEvent event) {System.out.println(name + " 已從會話中解綁,會話 ID: " + event.getSession().getId());}
}

以下是一個簡單的 Servlet 示例,用于演示如何將 User 對象存儲到 HttpSession 中:

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;@WebServlet("/testSessionBinding")
public class TestSessionBindingServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {HttpSession session = req.getSession();User user = new User("Alice");// 將對象綁定到會話session.setAttribute("user", user);// 模擬一段時間后移除對象,觸發解綁事件try {Thread.sleep(5000);} catch (InterruptedException e) {e.printStackTrace();}session.removeAttribute("user");}
}

代碼解釋

  • User
    • 實現了 HttpSessionBindingListener 接口。
    • valueBound 方法:當 User 對象被綁定到 HttpSession 時,會輸出相應信息,包括用戶名稱和會話 ID。
    • valueUnbound 方法:當 User 對象從 HttpSession 中解綁時,會輸出相應信息,包括用戶名稱和會話 ID。
  • TestSessionBindingServlet
    • 創建了一個 User 對象并將其存儲到 HttpSession 中,觸發 valueBound 方法。
    • 模擬等待 5 秒后,從 HttpSession 中移除該對象,觸發 valueUnbound 方法。

注意事項

  • 實現 HttpSessionBindingListener 的對象必須是可序列化的,因為在某些情況下(如會話持久化),對象可能需要被序列化和反序列化。
  • 綁定和解綁事件不僅會在調用 setAttributeremoveAttribute 方法時觸發,還會在會話過期或被銷毀時觸發 valueUnbound 方法。










5?? 參考 5

HttpSessionBindingListener 是一個接口,用于監聽對象被綁定到 HttpSession 或從 HttpSession 中移除的事件。當實現了 HttpSessionBindingListener 接口的對象被添加到 HttpSession 或從 HttpSession 中移除時,Servlet 容器會通知該對象,從而允許對象在綁定或移除時執行一些操作。

核心方法

  • valueBound(HttpSessionBindingEvent event):當對象被綁定到 HttpSession 時調用。
  • valueUnbound(HttpSessionBindingEvent event):當對象從 HttpSession 中移除時調用。

示例:在線人數統計

以下是一個利用 HttpSessionBindingListener 實現在線人數統計的示例:

User 類

User 類實現了 HttpSessionBindingListener 接口,用于監聽用戶登錄和退出事件:

import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener;public class User implements HttpSessionBindingListener {private int id;public User(int id) {this.id = id;}@Overridepublic void valueBound(HttpSessionBindingEvent event) {UserList.getInstance().addUser(this);}@Overridepublic void valueUnbound(HttpSessionBindingEvent event) {UserList.getInstance().removeUser(this);}public int getId() {return id;}
}
UserList 類

UserList 類用于管理在線用戶列表:

import java.util.Vector;public class UserList {private static UserList instance = new UserList();private Vector<User> users = new Vector<>();private UserList() {}public static UserList getInstance() {return instance;}public void addUser(User user) {if (!users.contains(user)) {users.add(user);}}public void removeUser(User user) {users.remove(user);}public int getUserCount() {return users.size();}
}
使用

在用戶登錄時,將 User 對象添加到 HttpSession

HttpSession session = request.getSession();
User user = new User(userId); // 假設 userId 是用戶的唯一標識
session.setAttribute("user", user);

在用戶退出時,從 HttpSession 中移除 User 對象:

HttpSession session = request.getSession();
User user = (User) session.getAttribute("user");
if (user != null) {session.removeAttribute("user");
}

特點

  • 不需要在 web.xml 中注冊監聽器。
  • 適用于需要在對象綁定到 HttpSession 或從 HttpSession 中移除時執行特定邏輯的場景。

通過這種方式,HttpSessionBindingListener 可以方便地實現在線人數統計、資源管理等功能。










6?? 參考 6

HttpSessionBindingListener 是一個接口,用于監聽 HTTP 會話(HttpSession)中屬性的綁定和解綁事件。通過實現這個接口,可以在對象的綁定和解綁時執行特定的代碼。

步驟:

  1. 創建一個類,實現 HttpSessionBindingListener 接口。
  2. 重寫兩個方法
    • valueBound(HttpSessionBindingEvent event):在對象被綁定到會話時調用。
    • valueUnbound(HttpSessionBindingEvent event):在對象從會話中解綁時調用。

代碼示例:

1. 創建監聽器類
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener;public class MySessionBindingListener implements HttpSessionBindingListener {private String name;public MySessionBindingListener(String name) {this.name = name;}@Overridepublic void valueBound(HttpSessionBindingEvent event) {System.out.println("對象綁定到會話,名稱: " + name);// 在這里執行對象綁定時的操作}@Overridepublic void valueUnbound(HttpSessionBindingEvent event) {System.out.println("對象從會話解綁,名稱: " + name);// 在這里執行對象解綁時的操作}
}
2. 使用監聽器類

在你的 Servlet 或其他組件中,將對象綁定到會話:

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;@WebServlet("/bind")
public class BindServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {HttpSession session = request.getSession();MySessionBindingListener listener = new MySessionBindingListener("TestObject");session.setAttribute("testObject", listener);}
}
3. 解綁對象

你可以在另一個 Servlet 或通過會話超時等方式將會話中的對象解綁:

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;@WebServlet("/unbind")
public class UnbindServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {HttpSession session = request.getSession(false);if (session != null) {session.removeAttribute("testObject");}}
}

解釋:

  • valueBound 方法:在對象被綁定到會話時調用,可以在這里進行一些初始化操作。
  • valueUnbound 方法:在對象從會話中解綁時調用,可以在這里進行一些清理操作。

通過這種方式,你可以監聽對象在會話中的綁定和解綁事件,執行相應的邏輯處理。










7?? 參考 7

在這里插入圖片描述

HttpSessionBindingListener 使用詳解

HttpSessionBindingListener 是 Java Servlet 規范中唯一由被存儲對象自身實現的會話監聽接口,用于感知對象與 session 的綁定/解綁事件。與 HttpSessionAttributeListener 不同,它直接內置于屬性對象中,無需額外配置監聽器。


一、核心方法實現

需在被存入 session 的對象中實現以下兩個方法:

import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener;public class UserSessionTracker implements HttpSessionBindingListener {private String username;public UserSessionTracker(String username) {this.username = username;}// 當對象被綁定到session時觸發(如session.setAttribute)@Overridepublic void valueBound(HttpSessionBindingEvent event) {System.out.println("用戶登錄綁定: " + username);System.out.println("Session ID: " + event.getSession().getId());}// 當對象從session移除時觸發(如session.removeAttribute或session過期)@Overridepublic void valueUnbound(HttpSessionBindingEvent event) {System.out.println("用戶解除綁定: " + username);System.out.println("觸發原因: " + (event.getSession().isNew() ? "新建會話" : "會話銷毀"));}
}

二、操作示例
在 Servlet 中使用綁定對象
protected void doGet(HttpServletRequest request, HttpServletResponse response) {HttpSession session = request.getSession();// 綁定對象(觸發valueBound)UserSessionTracker user = new UserSessionTracker("Alice");session.setAttribute("currentUser", user);  // 輸出:用戶登錄綁定: Alice// 解綁對象(觸發valueUnbound)session.removeAttribute("currentUser");     // 輸出:用戶解除綁定: Alice
}

三、與 HttpSessionAttributeListener 的對比
特性HttpSessionBindingListenerHttpSessionAttributeListener
實現位置由被存儲對象自身實現獨立監聽器類
事件觸發范圍僅監控特定對象的綁定/解綁監控所有session屬性變化
配置方式無需配置(自動感知)需通過@WebListener或web.xml注冊
典型應用場景對象需要感知自身生命周期全局監控屬性變化
會話數據獲取直接通過event.getSession()通過event.getSession()

四、高級應用場景
  1. 在線用戶統計

    public class OnlineUser implements HttpSessionBindingListener {private static AtomicInteger count = new AtomicInteger(0);@Overridepublic void valueBound(HttpSessionBindingEvent event) {count.incrementAndGet();System.out.println("當前在線人數: " + count.get());}@Overridepublic void valueUnbound(HttpSessionBindingEvent event) {count.decrementAndGet();System.out.println("當前在線人數: " + count.get());}
    }
    
  2. 資源自動釋放

    public class DatabaseConnection implements HttpSessionBindingListener {private Connection conn;public DatabaseConnection() {this.conn = DriverManager.getConnection(DB_URL);}@Overridepublic void valueUnbound(HttpSessionBindingEvent event) {if (conn != null && !conn.isClosed()) {conn.close();  // session失效時自動關閉數據庫連接}}
    }
    

五、注意事項
  1. 解綁觸發條件
    以下操作均會觸發 valueUnbound

    • 顯式調用 session.removeAttribute()
    • Session 超時(默認30分鐘)
    • 調用 session.invalidate()
    • 服務器重啟或應用重新部署
  2. 序列化要求
    若使用分布式會話,實現類必須支持 Serializable 接口

  3. 避免循環觸發
    不要在 valueBound 方法中修改當前對象的 session 狀態,例如:

    // 錯誤示例(導致遞歸調用)
    public void valueBound(HttpSessionBindingEvent event) {event.getSession().setAttribute("user", this); 
    }
    

相關問題

  1. 如何通過 HttpSessionBindingListener 實現分布式會話的跨服務器通知?
  2. 當同時使用 HttpSessionBindingListener 和 HttpSessionAttributeListener 時,事件觸發順序是怎樣的?
  3. 在 Spring Boot 中如何集成 HttpSessionBindingListener?










8?? 參考 8

HttpSessionBindingListener 是 Java Servlet 規范中用于實現 對象級會話屬性監控 的特殊監聽器接口,其核心特性是讓對象自身感知被綁定到 Session 或從 Session 中移除的事件。以下是其深度解析與實踐指南:


一、核心機制與接口方法

HttpSessionBindingListener 通過 對象自身實現監聽邏輯 的方式,精準控制會話屬性的生命周期,主要包含兩個方法:

  1. valueBound(HttpSessionBindingEvent event)
    觸發時機:當實現該接口的對象被綁定到 Session 中(如調用 session.setAttribute())時自動調用。
    典型用途
    ? 初始化用戶會話資源(如加載個性化配置)
    ? 在線用戶統計(將用戶 ID 加入全局在線列表)

    public class User implements HttpSessionBindingListener {@Overridepublic void valueBound(HttpSessionBindingEvent event) {String username = this.getName();ServletContext app = event.getSession().getServletContext();List<String> onlineUsers = (List<String>) app.getAttribute("onlineUsers");onlineUsers.add(username);  // 用戶登錄時加入在線列表}
    }
    
  2. valueUnbound(HttpSessionBindingEvent event)
    觸發時機:當對象從 Session 中移除(如 session.removeAttribute() 或 Session 超時銷毀)時觸發。
    典型用途
    ? 釋放會話資源(如關閉數據庫連接)
    ? 用戶登出時同步數據(如保存操作日志到數據庫)

    @Override
    public void valueUnbound(HttpSessionBindingEvent event) {String username = this.getName();UserService.saveLogoutTime(username);  // 記錄用戶退出時間
    }
    

二、實現步驟與代碼示例

  1. 對象實現接口
    創建需要會話感知的類(如 User),并實現接口方法:

    public class User implements HttpSessionBindingListener {private String id;private String name;// 構造方法、Getter/Setter...@Overridepublic void valueBound(HttpSessionBindingEvent event) {System.out.println("用戶 " + name + " 已登錄,Session ID:" + event.getSession().getId());}@Overridepublic void valueUnbound(HttpSessionBindingEvent event) {System.out.println("用戶 " + name + " 已退出,屬性名:" + event.getName());}
    }
    
  2. 綁定對象到 Session
    在 Servlet 或控制器中將對象存入 Session:

    User user = new User("U001", "Alice");
    request.getSession().setAttribute("currentUser", user);  // 觸發 valueBound()
    
  3. 移除對象
    顯式移除或 Session 超時后觸發解綁:

    request.getSession().removeAttribute("currentUser");  // 觸發 valueUnbound()
    

三、典型應用場景

場景實現方案技術要點
在線用戶統計對象綁定到 Session 時更新在線列表,解綁時移除用戶使用線程安全集合(如 CopyOnWriteArrayList)或原子類
資源生命周期管理對象解綁時自動釋放文件句柄或數據庫連接valueUnbound() 中調用 close() 方法并捕獲異常
操作審計記錄用戶登錄/退出時間、IP 地址等關鍵信息通過 event.getSession() 獲取會話上下文
動態權限更新用戶角色屬性變更時,實時刷新權限緩存結合 attributeReplaced 事件實現雙向同步

四、核心優勢與注意事項

  1. 對象級精準控制
    HttpSessionAttributeListener 不同,HttpSessionBindingListener 的監聽邏輯 內聚在對象自身,無需全局監聽所有屬性變化。

  2. 零配置特性
    無需在 web.xml 或注解中聲明,只需對象實現接口即可生效。

  3. 事件觸發條件
    ? 綁定:僅當對象首次存入 Session 或替換為相同屬性名時觸發 valueBound()
    ? 解綁:除顯式移除外,Session 失效、服務器重啟也會觸發 valueUnbound()

  4. 并發安全建議
    ? 在線用戶列表等共享資源需使用 synchronized 或并發集合類
    ? 避免在監聽方法中執行阻塞式 I/O 操作


五、與 HttpSessionListener 的對比

特性HttpSessionBindingListenerHttpSessionListener
監聽粒度對象級別(特定屬性)會話級別(所有會話)
配置方式無需配置,由對象自身實現需在 web.xml 或注解中聲明
適用場景精準控制單個對象的會話生命周期全局會話創建/銷毀事件(如統計活躍會話數)
資源消耗低(僅針對特定對象)高(監聽所有會話)










9?? 參考 9

HttpSessionBindingListener是一個用于監聽HttpSession對象中屬性綁定和解綁事件的接口,其用法主要包括以下幾個方面:

  1. 接口定義與方法

    • valueBound(HttpSessionBindingEvent event):當一個實現了HttpSessionBindingListener接口的對象被綁定到HttpSession中時觸發此方法[2][3][5]。
    • valueUnbound(HttpSessionBindingEvent event):當一個實現了HttpSessionBindingListener接口的對象從HttpSession中解綁時觸發此方法[2][3][5]。
  2. 實現類

    • 創建一個類實現HttpSessionBindingListener接口,并重寫上述兩個方法。例如,可以創建一個名為MySessionBindingListener的類,并在其中實現valueBoundvalueUnbound方法[2][3][4][5]。
  3. 注冊監聽器

    • 在代碼中創建該監聽器的實例,并將其綁定到HttpSession對象上。通常使用session.setAttribute("attributeName", listenerInstance)的方法將監聽器保存到session中[2][3][4][5]。
  4. 應用場景舉例

    • 用戶在線狀態跟蹤:通過監聽用戶的綁定和解綁事件,可以實時更新用戶的在線狀態列表[1][5]。
    • 資源管理:在屬性綁定時分配必要的資源(如數據庫連接、文件句柄等),并在屬性解綁時釋放這些資源,以防止資源泄漏[1]。
    • 權限驗證:在屬性綁定或解綁時進行用戶身份驗證和權限檢查,確保只有合法的用戶才能訪問受保護的資源[1]。
    • 日志記錄:記錄屬性的綁定和解綁事件,以便進行審計和故障排查[1]。
    • 數據緩存:當某些數據被添加到session中作為緩存使用時,可以在屬性解綁時及時更新或清理緩存,以保證數據的一致性[1]。

HttpSessionBindingListener 是 Java Web 開發中用于監聽 對象被綁定到 HttpSession 或從 HttpSession 解除綁定的接口。它允許對象自身在被放入或移出會話時執行自定義邏輯(如初始化、清理資源、記錄日志等)。以下是其核心用法:


核心方法

  1. valueBound(HttpSessionBindingEvent event)

    • 當對象被綁定到會話(即通過 session.setAttribute(name, this) 放入會話時)觸發。
    • 典型用途:初始化對象狀態、記錄日志、綁定資源。
  2. valueUnbound(HttpSessionBindingEvent event)

    • 當對象從會話中解除綁定(即通過 session.removeAttribute(name) 或會話銷毀時)觸發。
    • 典型用途:釋放資源、記錄操作、執行清理邏輯。

使用步驟

  1. 在目標對象中實現接口
    需要監聽的對象類需實現 HttpSessionBindingListener 接口,并重寫兩個方法:

    import javax.servlet.http.HttpSessionBindingEvent;
    import javax.servlet.http.HttpSessionBindingListener;public class User implements HttpSessionBindingListener {private String username;// 構造函數、Getter/Setter 省略@Overridepublic void valueBound(HttpSessionBindingEvent event) {System.out.println("用戶 " + username + " 已綁定到會話:" + event.getSession().getId());// 初始化邏輯(如記錄登錄時間、分配資源)}@Overridepublic void valueUnbound(HttpSessionBindingEvent event) {System.out.println("用戶 " + username + " 已解除綁定,會話 ID:" + event.getSession().getId());// 清理邏輯(如關閉連接、記錄下線時間)}
    }
    
  2. 將對象存入/移出會話
    直接通過 HttpSession.setAttribute()removeAttribute() 操作觸發事件:

    // 將 User 對象存入會話時觸發 valueBound
    session.setAttribute("user", user);// 移除 User 對象時觸發 valueUnbound
    session.removeAttribute("user");
    

典型應用場景

  1. 用戶登錄/退出時的邏輯

    • 當用戶對象被存入會話時(valueBound):記錄登錄時間、初始化權限信息。
    • 當用戶對象被移出會話時(valueUnbound):記錄登出時間、釋放資源(如關閉數據庫連接)。
  2. 資源管理

    • valueBound 中分配臨時資源(如文件句柄、線程池),在 valueUnbound 中釋放資源,避免內存泄漏。
  3. 狀態同步

    • 當對象被綁定到會話時,同步其狀態到其他服務(如 Redis 緩存)。

HttpSessionAttributeListener 的區別

特性HttpSessionBindingListenerHttpSessionAttributeListener
觸發對象對象自身(需實現接口)監聽器類(獨立于屬性對象)
監聽范圍對象被綁定/解除綁定時觸發會話中所有屬性的增刪改事件
方法參數事件對象(包含會話和自身對象信息)事件對象(包含屬性名、值及會話)
典型用途對象自身需要執行綁定/解除綁定的邏輯(如資源分配)監控會話屬性的全局變化(如統計屬性數量、日志記錄)

注意事項

  • 對象必須實現接口:只有實現了 HttpSessionBindingListener 的對象才能觸發其方法。
  • 線程安全:對象可能在多個請求中被并發訪問,需確保方法內的操作線程安全。
  • 會話銷毀時的觸發:當會話被銷毀時,所有綁定的屬性對象的 valueUnbound 方法會被自動調用(除非會話未正常關閉,如強制停止服務器)。

示例場景

假設有一個 Cart 對象管理購物車,需要在綁定到會話時加載緩存數據,解除綁定時保存數據:

public class Cart implements HttpSessionBindingListener {private List<Product> items;@Overridepublic void valueBound(HttpSessionBindingEvent event) {// 從數據庫或緩存加載購物車數據items = loadCartFromDatabase(event.getSession().getId());}@Overridepublic void valueUnbound(HttpSessionBindingEvent event) {// 保存購物車到數據庫saveCartToDatabase(items);}
}

通過 HttpSessionBindingListener,你可以讓對象自身直接參與會話綁定的生命周期管理,實現更細粒度的資源控制和業務邏輯。










🔟 參考 10

HttpSessionBindingListener 用于監聽 對象綁定到 HttpSession 或從 Session 解綁 的事件,其核心用法如下:


1. 接口定義

當某個對象實現了 HttpSessionBindingListener 接口并存儲到 Session 中時,Servlet 容器會在對象綁定或解綁時觸發回調方法。
核心方法

  • valueBound(HttpSessionBindingEvent event):對象被綁定到 Session 時觸發
  • valueUnbound(HttpSessionBindingEvent event):對象從 Session 解綁時觸發

2. 實現步驟

(1) 創建監聽對象

需讓某個 JavaBean 實現 HttpSessionBindingListener 接口,并重寫方法。
示例代碼:

public class User implements HttpSessionBindingListener {private String username;// 構造方法、getter/setter 省略@Overridepublic void valueBound(HttpSessionBindingEvent event) {System.out.println("用戶 " + username + " 已綁定到 Session");// 可在此初始化資源(如數據庫連接)}@Overridepublic void valueUnbound(HttpSessionBindingEvent event) {System.out.println("用戶 " + username + " 已從 Session 解綁");// 可在此釋放資源(如關閉數據庫連接)}
}
(2) 將對象存入 Session

在 Servlet 中通過 session.setAttribute() 將對象綁定到 Session:

@WebServlet("/login")
public class LoginServlet extends HttpServlet {protected void doPost(HttpServletRequest request, HttpServletResponse response) {User user = new User("Alice");request.getSession().setAttribute("user", user);  // 觸發 valueBound()}
}
(3) 觸發解綁

當 Session 超時、調用 session.invalidate() 或手動移除屬性時,觸發 valueUnbound()

// 手動移除屬性
request.getSession().removeAttribute("user");  // 觸發 valueUnbound()// Session 超時自動解綁(需配置超時時間)

3. 應用場景

  • 用戶登錄狀態管理
    用戶登錄時綁定到 Session,退出或超時自動解綁,記錄登錄/登出日志。
  • 資源初始化與釋放
    對象綁定到 Session 時初始化資源(如數據庫連接),解綁時釋放資源。
  • 在線用戶統計
    結合單例集合(如 Vector),在 valueBound() 中添加用戶,在 valueUnbound() 中移除用戶。

4. 與 HttpSessionAttributeListener 的區別

特性HttpSessionBindingListenerHttpSessionAttributeListener
監聽對象對象自身(需實現接口)Session 中所有屬性
觸發條件對象被綁定/解綁到 SessionSession 屬性增刪改
使用場景單個對象的狀態管理(如用戶登錄)監控所有 Session 屬性變化

5. 注意事項

  • 生命周期:監聽器的生命周期與綁定的 Session 一致。
  • 唯一標識:若需區分不同對象,可通過構造方法傳遞唯一標識(如用戶 ID)。
  • 觸發時機valueUnbound() 可能在以下情況觸發:
    • 調用 session.invalidate()
    • Session 超時
    • 手動移除屬性(session.removeAttribute())。

通過上述方式,HttpSessionBindingListener 可以精準監聽特定對象的綁定狀態,適用于需要對象級狀態管理的場景。



















本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/77290.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/77290.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/77290.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【HDFS入門】HDFS高可用性與容錯機制深度解析

目錄 引言 1 HDFS高可用架構實現 1.1 基于QJM的NameNode HA架構 1.2 QJM vs NFS實現對比 2 故障切換流程與ZooKeeper作用 2.1 自動故障轉移流程 2.2 狀態轉換機制 3 數據恢復與副本管理 3.1 DataNode故障處理流程 4 快照與數據保護機制 4.1 HDFS快照架構 4.2 快照使…

04-libVLC的視頻播放器:獲取媒體信息

libvlc_media_t* libvlc_media_player_get_media(libvlc_media_player_t* p_mi); 功能說明 核心作用:獲取與媒體播放器關聯的當前媒體對象返回值:成功:返回libvlc_media_t*指針失敗/無關聯媒體:返回NULL內存管理:返回的媒體對象引用計數會增加,需要使用libvlc_media_rele…

使用datax通過HbaseShell封裝writer和reader同步hbase數據到hbase_踩坑_細節總結---大數據之DataX工作筆記008

最近在做大數據相關功能,有個需求,使用datax同步hbase到hbase中,其中還是有很多細節值得記錄: 首先來看一下datax的源碼中,如果你使用phoenix創建的表,那么 你就需要使用對應的hbase帶有sql字樣的,reader和writer. 然后如果你使用datax-web來進行測試的,那么,他默認使用的是h…

如何通過window端來ssh連接本地虛擬機的ubuntu

首先在 Ubuntu 虛擬機上安裝和配置 SSH 服務&#xff1a; # 安裝 SSH 服務器 sudo apt update sudo apt install openssh-server# 檢查 SSH 服務狀態 sudo systemctl status ssh# 如果沒有啟動&#xff0c;則啟動 SSH 服務 sudo systemctl start ssh# 設置開機自啟動 sudo sys…

Anolis OS 8.10 發布:軟硬協同優化,滿足多行業實際應用需求

引言 龍蜥操作系統 Anolis OS 8 是 OpenAnolis 龍蜥社區發行的開源 Linux 發行版&#xff0c;支持多計算架構&#xff0c;提供穩定、高性能、安全、可靠的操作系統支持。Anolis OS 8.10 是 Anolis OS 8 發布的第六個小版本&#xff0c;通過軟硬協同&#xff0c;不斷完善生態&a…

Java八種常見的設計模式

一、單例模式 單例模式是&#xff08;Singleton Pattern&#xff09;Java中最常用的設計模式之一&#xff0c;它保證一個類僅有一個實例&#xff0c;并提供一個全局訪問點。 實現單例模式的核心是將類的構造方法私有化&#xff0c;以防止外部直接通過構造函數創建實例。同時&am…

4.17---實現商鋪和緩存與數據庫雙寫一致以及宕機處理

實現商鋪和緩存與數據庫雙寫一致&#xff08;以及強雙寫一致策略&#xff09; redis點評項目采用的是延時雙刪策略 雙刪&#xff1a; 我們更新完數據庫之后刪除緩存&#xff0c;這樣即使有線程并發進來查詢&#xff0c;會發現緩存中沒有數據&#xff0c;從而會去mysql中查找…

滑動窗口209. 長度最小的子數組

1.題目 給定一個含有 n 個正整數的數組和一個正整數 target 。 找出該數組中滿足其總和大于等于 target 的長度最小的 子數組 [numsl, numsl1, ..., numsr-1, numsr] &#xff0c;并返回其長度。如果不存在符合條件的子數組&#xff0c;返回 0 。 示例 1&#xff1a; 輸入&…

osu ai 論文筆記 DQN

e https://theses.liacs.nl/pdf/2019-2020-SteeJvander.pdf Creating an AI for the Rhytm Game osu! 20年的論文 用監督學習訓練移動模型100首歌能達到95準確率 點擊模型用DQN兩千首歌65準確率 V抖用的居然不是強化學習&#xff1f; 5,6星打96準確度還是有的東西的 這是5.…

如何通過工具實現流程自動化

通過自動化工具&#xff0c;企業可以顯著提高工作效率、降低人為錯誤、節省時間和成本。現代企業的運營中&#xff0c;流程管理是確保工作順暢的關鍵&#xff0c;而人工處理繁瑣的流程不僅容易出錯&#xff0c;還會消耗大量的時間和人力資源。通過使用適合的自動化工具&#xf…

mongodb 4.0+多文檔事務的實現原理

1. 副本集事務實現&#xff08;4.0&#xff09;? ?非嚴格依賴二階段提交? MongoDB 4.0 在副本集環境中通過 ?全局邏輯時鐘&#xff08;Logical Clock&#xff09;? 和 ?快照隔離&#xff08;Snapshot Isolation&#xff09;? 實現多文檔事務&#xff0c;事務提交時通過…

《理解 Java 泛型中的通配符:extends 與 super 的使用場景》

大家好呀&#xff01;&#x1f44b; 今天我們要聊一個讓很多Java初學者頭疼的話題——泛型通配符。別擔心&#xff0c;我會用最通俗易懂的方式&#xff0c;帶你徹底搞懂這個看似復雜的概念。準備好了嗎&#xff1f;Let’s go! &#x1f680; 一、為什么我們需要泛型通配符&…

速盾:高防CDN訪問多了會影響源站嗎?

在當今數字化時代&#xff0c;內容分發網絡&#xff08;CDN&#xff09;已經成為保障網站性能和用戶體驗的重要工具。特別是高防CDN&#xff0c;它不僅能夠加速內容傳輸&#xff0c;還能有效抵御各種類型的網絡攻擊&#xff0c;確保業務的連續性和穩定性。然而&#xff0c;一些…

Unity URP Moblie AR示例工程,真機打包出來,沒陰影

效果&#xff1a; unity ar示例演示 現象&#xff1a; 真機打包測試私活沒有陰影 Unity版本&#xff1a;2022.3.4f1c1 分析原因&#xff1a; Prefab &#xff1a;ARFeatheredPlane中也有材質&#xff0c;一個用于環境遮擋&#xff0c;一個用于陰影接受。 按理說有啊。 urp …

win10下github libiec61850庫編譯調試sntp_example

libiec61850 https://github.com/mz-automation/libiec61850 v1.6 簡介 libiec61850 是一個開源&#xff08;GPLv3&#xff09;的 IEC 61850 客戶端和服務器庫實現&#xff0c;支持 MMS、GOOSE 和 SV 協議。它使用 C 語言&#xff08;根據 C99 標準&#xff09;實現&#xf…

Microsoft SQL Server Management 一鍵刪除數據庫所有外鍵

DECLARE ESQL VARCHAR(1000); DECLARE FCursor CURSOR --定義游標 FOR (SELECT ALTER TABLE O.name DROP CONSTRAINT F.name; AS CommandSQL from SYS.FOREIGN_KEYS F JOIN SYS.ALL_OBJECTS O ON F.PARENT_OBJECT_ID O.OBJECT_ID WHERE O.TYPE U AND F.TYPE …

新型多機器人協作運輸系統,輕松應對復雜路面

受到魚類、鳥類和螞蟻等微小生物體協作操縱的啟發&#xff0c;研究人員開發了多機器人協作運輸系統&#xff08;Multirobot Cooperative Transportation Systems&#xff0c;MRCTS&#xff09;運輸單個機器人無法處理的重型超大物體&#xff0c;可用于搜救行動、災難響應、軍事…

Framework Binder架構分解

整個 Binder 架構所涉及的總共有以下 5 個目錄&#xff1a; 1. /framework/base/core/java/(Java) 2. /framework/base/core/jni/ (JNI) 3&#xff0c;/framework/native/libs/binder (Native) 4&#xff0c;/framework/native/cmds/servicemanager/ (Native) 5&#xff0c…

騰訊云對象存儲以及項目業務頭像上傳

騰訊云上傳步驟&#xff1a; service-vod模塊化中 ①、參考文檔&#xff0c;引入依賴 ②、配置文件application.properties ③、創建工具類 初始化bean的時候讀取配置文件 Component public class ConstantPropertiesUtil implements InitializingBean{Value("${t…

LeetCode hot 100—括號生成

題目 數字 n 代表生成括號的對數&#xff0c;請你設計一個函數&#xff0c;用于能夠生成所有可能的并且 有效的 括號組合。 示例 示例 1&#xff1a; 輸入&#xff1a;n 3 輸出&#xff1a;["((()))","(()())","(())()","()(())",&…