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.mzph.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;["((()))","(()())","(())()","()(())",&…