当前位置: 首页 > news >正文

ServletContextAttributeListener 的用法笔记250417

ServletContextAttributeListener 的用法笔记250417

在这里插入图片描述

以下是关于 ServletContextAttributeListener 的用法详解,涵盖核心方法、实现场景、注意事项及最佳实践,帮助您有效监听应用级别属性(ServletContext)的变化:


1. 核心功能

ServletContextAttributeListener 用于监听 应用级别属性(ServletContext 中的属性)的增删改事件。适用于跟踪全局配置变更、动态资源加载等场景。


2. 核心方法

  • attributeAdded(ServletContextAttributeEvent event)
    当向 ServletContext 中添加新属性时触发。

  • attributeRemoved(ServletContextAttributeEvent event)
    当从 ServletContext 中移除属性时触发。

  • attributeReplaced(ServletContextAttributeEvent event)
    ServletContext 中的属性被替换时触发(新旧值均可获取)。


3. 实现步骤

步骤 1:创建监听器类
import javax.servlet.ServletContextAttributeEvent;
import javax.servlet.ServletContextAttributeListener;
import javax.servlet.annotation.WebListener;@WebListener
public class AppAttributeListener implements ServletContextAttributeListener {@Overridepublic void attributeAdded(ServletContextAttributeEvent event) {String name = event.getName();Object value = event.getValue();System.out.println("[新增] 应用属性: " + name + " = " + value);}@Overridepublic void attributeRemoved(ServletContextAttributeEvent event) {String name = event.getName();System.out.println("[移除] 应用属性: " + name);}@Overridepublic void attributeReplaced(ServletContextAttributeEvent event) {String name = event.getName();// 获取旧值(被替换前的值)Object oldValue = event.getValue();// 获取新值(需通过 ServletContext 获取)Object newValue = event.getServletContext().getAttribute(name);System.out.println("[替换] 应用属性: " + name + " | 旧值: " + oldValue + " → 新值: " + newValue);}
}
步骤 2:注册监听器
  • 方式一:通过 web.xml 配置

    <web-app><listener><listener-class>com.example.AppAttributeListener</listener-class></listener>
    </web-app>
    
  • 方式二:使用 @WebListener 注解(Servlet 3.0+)
    直接在类上添加注解即可。


4. 典型应用场景

  • 动态配置热更新
    监听配置属性(如数据库地址)变更,触发资源重新加载。

    public void attributeReplaced(ServletContextAttributeEvent event) {if ("dbConfig".equals(event.getName())) {reloadDatabaseConnection(); // 重新初始化数据库连接池}
    }
    
  • 全局状态监控
    跟踪关键属性(如系统模式切换为“维护模式”)变化,并广播通知其他模块。

    public void attributeAdded(ServletContextAttributeEvent event) {if ("maintenanceMode".equals(event.getName())) {sendAlert("系统进入维护状态!");}
    }
    
  • 多模块协作
    当某个模块向 ServletContext 中发布服务对象时,自动注册到其他模块。

    public void attributeAdded(ServletContextAttributeEvent event) {if (event.getName().startsWith("service.")) {ServiceRegistry.register(event.getName(), event.getValue());}
    }
    
  • 审计日志
    记录所有全局属性的变更历史,用于安全审计或故障排查。

    public void attributeReplaced(ServletContextAttributeEvent event) {logAuditTrail("属性修改", event.getName(), event.getValue(), // 旧值event.getServletContext().getAttribute(event.getName()) // 新值);
    }
    

5. 注意事项

(1) 线程安全问题
  • ServletContext 是应用全局共享的,属性操作可能被多线程同时触发。需确保监听器逻辑线程安全(如避免对共享资源的非原子操作)。
(2) 性能影响
  • 频繁的属性变更(如高并发场景下动态更新)可能导致监听器被多次调用,需优化代码避免阻塞主流程。
(3) 避免循环触发
  • 在监听器中修改 ServletContext 属性可能导致递归调用(例如在 attributeAdded 中再次修改属性),需谨慎处理。
(4) 属性序列化
  • 若应用支持分布式部署(集群),ServletContext 属性可能需要序列化。确保监听器处理的对象实现 Serializable 接口。
(5) 新旧值获取
  • attributeReplaced 方法中,event.getValue() 返回的是 旧值,新值需通过 event.getServletContext().getAttribute(name) 获取。

6. 与其他监听器对比

监听器作用对象触发时机典型用途
ServletContextListenerServletContext应用启动/关闭全局资源初始化/销毁
ServletContextAttributeListenerServletContext 属性属性增删改配置热更新、状态监控
HttpSessionAttributeListenerHttpSession 属性会话属性增删改用户状态跟踪、会话数据同步
监听器类型监听对象典型用途
ServletContextAttributeListenerWeb应用全局属性变化动态配置、全局缓存管理
HttpSessionAttributeListener单个用户会话属性变化用户个性化设置跟踪
ServletRequestAttributeListener单个请求属性变化请求级参数处理(较少使用)

7. 最佳实践

  • 轻量级操作:避免在监听器中执行耗时任务(如复杂计算、远程调用),优先使用异步处理。
  • 结合配置中心:在微服务架构中,可通过监听器实现与配置中心(如 Spring Cloud Config)的动态集成。
  • 防御性编程:检查属性值的合法性,避免因非法值导致系统异常。
    public void attributeAdded(ServletContextAttributeEvent event) {if ("maxThreads".equals(event.getName())) {if (!(event.getValue() instanceof Integer)) {throw new IllegalArgumentException("maxThreads 必须为整数");}}
    }
    

总结

ServletContextAttributeListener 是监控全局属性变更的关键工具,适用于动态配置管理、状态同步及安全审计。重点在于正确处理属性增删改事件、确保线程安全,并避免因监听逻辑导致的性能瓶颈或递归问题。结合其他上下文监听器,可构建灵活的应用级事件响应机制。










1️⃣ 参考 1

ServletContextAttributeListener 是 Java Servlet 规范中用于监听全局应用作用域(ServletContext)属性变化的接口。当应用在全局作用域中添加替换移除属性时,会触发对应的监听方法。以下是其核心用法、示例及典型场景:


核心用法步骤

1. 实现 ServletContextAttributeListener 接口
import javax.servlet.ServletContextAttributeEvent;
import javax.servlet.ServletContextAttributeListener;
import javax.servlet.annotation.WebListener;@WebListener // Servlet 3.0+ 使用注解(无需 web.xml)
public class MyContextAttrListener implements ServletContextAttributeListener {@Overridepublic void attributeAdded(ServletContextAttributeEvent event) {// 属性被添加时触发String name = event.getName();Object value = event.getValue();System.out.println("全局属性添加: " + name + " = " + value);}@Overridepublic void attributeReplaced(ServletContextAttributeEvent event) {// 属性被替换时触发(旧值可通过 event.getValue() 获取)String name = event.getName();Object oldValue = event.getValue();Object newValue = event.getServletContext().getAttribute(name);System.out.println("全局属性替换: " + name + " | 旧值=" + oldValue + ", 新值=" + newValue);}@Overridepublic void attributeRemoved(ServletContextAttributeEvent event) {// 属性被移除时触发String name = event.getName();Object value = event.getValue();System.out.println("全局属性移除: " + name + " = " + value);}
}
2. 配置监听器
  • 方式一:使用 web.xml(兼容所有版本)
    <listener><listener-class>com.example.MyContextAttrListener</listener-class>
    </listener>
    
  • 方式二:使用 @WebListener 注解(Servlet 3.0+)
    直接在类上添加注解即可(如上例)。

典型应用场景

1. 全局配置变更日志
@Override
public void attributeReplaced(ServletContextAttributeEvent event) {String name = event.getName();if ("appConfig".equals(name)) {// 当全局配置更新时,记录变更日志Properties oldConfig = (Properties) event.getValue();Properties newConfig = (Properties) event.getServletContext().getAttribute(name);log.info("全局配置更新: " + diff(oldConfig, newConfig));}
}
2. 动态刷新资源
@Override
public void attributeAdded(ServletContextAttributeEvent event) {if ("cacheManager".equals(event.getName())) {// 当缓存管理器被初始化时,预加载缓存CacheManager manager = (CacheManager) event.getValue();manager.preload();}
}@Override
public void attributeReplaced(ServletContextAttributeEvent event) {if ("cacheManager".equals(event.getName())) {// 当缓存管理器被替换时,关闭旧实例CacheManager oldManager = (CacheManager) event.getValue();oldManager.shutdown();}
}
3. 依赖属性自动更新
@Override
public void attributeReplaced(ServletContextAttributeEvent event) {if ("dbConfig".equals(event.getName())) {// 当数据库配置更新时,重新初始化连接池DataSource oldDataSource = (DataSource) event.getServletContext().getAttribute("dataSource");oldDataSource.close();DataSource newDataSource = createDataSource(event.getServletContext());event.getServletContext().setAttribute("dataSource", newDataSource);}
}

注意事项

  1. 线程安全问题
    ServletContext 是全局共享的,多个线程可能同时修改属性。需确保监听器中的逻辑是线程安全的(例如避免对共享资源的非原子操作)。

  2. 避免递归触发
    在监听器中修改 ServletContext 属性可能导致无限递归。例如:

    public void attributeAdded(ServletContextAttributeEvent event) {event.getServletContext().setAttribute("key", "newValue"); // 危险操作!
    }
    

    解决方案:添加条件判断或使用状态标志。

  3. 新旧值获取

    • attributeReplaced 方法中,event.getValue() 返回旧值,新值需通过 event.getServletContext().getAttribute(name) 获取。
  4. 性能影响
    监听器的逻辑应尽量轻量,避免阻塞全局作用域操作。


与其他监听器的协作

监听器作用范围触发时机典型用途
ServletContextListener全局应用应用启动/关闭时初始化全局配置、连接池
ServletContextAttributeListener全局属性属性添加/替换/移除时配置变更日志、资源刷新
HttpSessionAttributeListener会话属性会话属性添加/替换/移除时用户登录状态跟踪

总结

ServletContextAttributeListener 是监控全局作用域属性变化的核心工具,适用于配置管理、资源刷新、变更审计等场景。通过合理使用,可实现应用配置的动态更新和全局状态的精细化管理。










2️⃣ 参考 2

以下是 ServletContextAttributeListener 的详细用法说明,结合知识库中的信息和实际应用场景:


1. 核心方法

ServletContextAttributeListener 是 Java Web 开发中用于监听 ServletContext 对象属性变化的接口,主要用于在以下操作时触发回调方法:

  • attributeAdded(ServletContextAttributeEvent event)
    当向 ServletContext(即全局 application 域)添加新属性时调用。
  • attributeRemoved(ServletContextAttributeEvent event)
    当从 ServletContext 删除属性时调用。
  • attributeReplaced(ServletContextAttributeEvent event)
    替换(修改)ServletContext 中的属性时调用(例如用新值覆盖旧值)。

2. 实现步骤

步骤 1:创建监听器类

实现 ServletContextAttributeListener 接口,并重写上述方法。

import javax.servlet.ServletContextAttributeEvent;
import javax.servlet.ServletContextAttributeListener;
import javax.servlet.annotation.WebListener;@WebListener  // 使用注解注册(Servlet 3.0+)
public class MyServletContextAttributeListener implements ServletContextAttributeListener {@Overridepublic void attributeAdded(ServletContextAttributeEvent event) {String attributeName = event.getName();Object attributeValue = event.getValue();System.out.println("属性 [" + attributeName + "] 被添加,值为: " + attributeValue);// 可执行其他操作,如日志记录或通知}@Overridepublic void attributeRemoved(ServletContextAttributeEvent event) {String attributeName = event.getName();Object oldValue = event.getValue();  // 被删除的旧值System.out.println("属性 [" + attributeName + "] 被删除,旧值为: " + oldValue);}@Overridepublic void attributeReplaced(ServletContextAttributeEvent event) {String attributeName = event.getName();Object oldValue = event.getValue();  // 被替换的旧值Object newValue = event.getServletContext().getAttribute(attributeName);  // 新值System.out.println("属性 [" + attributeName + "] 被替换,旧值: " + oldValue + " → 新值: " + newValue);}
}
步骤 2:注册监听器

有两种方式注册监听器:

方式 1:在 web.xml 中配置
<web-app><!-- 其他配置 --><listener><listener-class>com.example.MyServletContextAttributeListener</listener-class></listener>
</web-app>
方式 2:使用注解(Java EE 6+)

在监听器类上添加 @WebListener 注解(如示例代码中所示)。


3. 典型应用场景

场景 1:监控全局属性变化

记录 ServletContext 属性的增删改操作,用于调试或审计:

@Override
public void attributeAdded(ServletContextAttributeEvent event) {System.out.println("全局属性 [" + event.getName() + "] 添加成功,值为:" + event.getValue());// 可记录到日志文件或数据库
}@Override
public void attributeReplaced(ServletContextAttributeEvent event) {System.out.println("全局属性 [" + event.getName() + "] 被覆盖,旧值:" + event.getValue());
}
场景 2:动态配置管理

在属性变化时触发业务逻辑,例如:

  • 当配置属性(如 max_connections)被修改时,重新加载数据库连接池。
  • cache_enabled 属性被设置为 false 时,禁用缓存。
@Override
public void attributeReplaced(ServletContextAttributeEvent event) {if ("cache_enabled".equals(event.getName())) {Boolean newValue = (Boolean) event.getServletContext().getAttribute("cache_enabled");if (!newValue) {System.out.println("全局缓存已禁用");// 执行缓存清理操作}}
}
场景 3:资源管理

在属性被删除时释放资源:

@Override
public void attributeRemoved(ServletContextAttributeEvent event) {if ("databaseConnection".equals(event.getName())) {Connection conn = (Connection) event.getValue();if (conn != null) {try {conn.close();} catch (SQLException e) {e.printStackTrace();}}}
}

4. 生命周期说明

  • 触发条件
    • attributeAdded:调用 application.setAttribute(name, value) 时。
    • attributeRemoved:调用 application.removeAttribute(name) 时。
    • attributeReplaced:对已存在的属性调用 application.setAttribute(name, newValue) 时(旧值被替换)。
  • 执行顺序
    • 监听器方法在属性操作完成后立即触发,无需手动调用。

5. 注意事项

  1. 线程安全
    • ServletContext 是全局共享对象,多个请求可能同时修改属性。需确保监听器逻辑本身是线程安全的(例如避免非线程安全的共享变量)。
  2. 事件顺序
    • 替换属性时,attributeReplaced 方法中的 event.getValue() 返回的是旧值,新值需通过 application.getAttribute(name) 获取。
  3. ServletContextListener 的区别
    • ServletContextListener 监听的是 ServletContext 对象的创建和销毁(应用启动/关闭)。
    • ServletContextAttributeListener 监听的是 ServletContext 对象属性的变化

6. 完整示例

以下是一个完整的监听器示例,结合了日志记录和资源管理:

import javax.servlet.ServletContextAttributeEvent;
import javax.servlet.ServletContextAttributeListener;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSession;
import java.sql.Connection;
import java.sql.SQLException;@WebListener
public class GlobalAttributeMonitor implements ServletContextAttributeListener {@Overridepublic void attributeAdded(ServletContextAttributeEvent event) {log("添加", event.getName(), event.getValue(), null);}@Overridepublic void attributeRemoved(ServletContextAttributeEvent event) {// 释放资源示例(如数据库连接)if ("databaseConnection".equals(event.getName())) {Connection conn = (Connection) event.getValue();if (conn != null) {try {conn.close();} catch (SQLException e) {e.printStackTrace();}}}log("删除", event.getName(), event.getValue(), null);}@Overridepublic void attributeReplaced(ServletContextAttributeEvent event) {Object oldValue = event.getValue();Object newValue = event.getServletContext().getAttribute(event.getName());log("替换", event.getName(), oldValue, newValue);}private void log(String action, String name, Object oldValue, Object newValue) {if ("替换".equals(action)) {System.out.println("属性 [" + name + "] 被" + action + ",旧值: " + oldValue + " → 新值: " + newValue);} else {System.out.println("属性 [" + name + "] 被" + action + ",值为: " + oldValue);}}
}

7. 测试示例

在某个 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.ServletContext;@WebServlet("/test-attribute")
public class TestServlet extends HttpServlet {protected void doGet(HttpServletRequest request, HttpServletResponse response) {ServletContext application = getServletContext();// 触发 attributeAddedapplication.setAttribute("testKey", "初始值");// 触发 attributeReplacedapplication.setAttribute("testKey", "新值");// 触发 attributeRemovedapplication.removeAttribute("testKey");}
}

8. 总结

ServletContextAttributeListener 是监控 全局属性变化 的核心工具,适用于配置管理、资源控制和审计场景。通过实现三个方法,可以精确控制属性的增删改操作,确保应用行为符合预期。结合 @WebListener 注解简化配置,同时注意线程安全和事件顺序,能够高效管理 ServletContext 的属性生命周期。










3️⃣ 参考 3

ServletContextAttributeListener 是 Java Web 开发中用于监听 Web 应用上下文(ServletContext)属性变化 的接口。它允许你在应用级别(而非单个用户会话)的属性被添加、移除或替换时执行自定义逻辑。以下是其核心用法:

一、核心作用

  1. 属性添加时:监听 setAttribute() 方法调用。
  2. 属性移除时:监听 removeAttribute() 方法调用。
  3. 属性替换时:监听 setAttribute() 覆盖已有属性的操作。

二、实现步骤

1. 创建监听器类

实现 javax.servlet.ServletContextAttributeListener 接口,重写三个方法:

import javax.servlet.annotation.WebListener;
import javax.servlet.ServletContextAttributeEvent;
import javax.servlet.ServletContextAttributeListener;
import java.util.concurrent.ConcurrentHashMap;@WebListener // 注解方式(Servlet 3.0+)
public class AppConfigListener implements ServletContextAttributeListener {private static final ConcurrentHashMap<String, Object> configCache = new ConcurrentHashMap<>();@Overridepublic void attributeAdded(ServletContextAttributeEvent event) {String name = event.getName();Object value = event.getValue();configCache.put(name, value);System.out.println("新配置添加: " + name + " = " + value);}@Overridepublic void attributeRemoved(ServletContextAttributeEvent event) {String name = event.getName();configCache.remove(name);System.out.println("配置移除: " + name);}@Overridepublic void attributeReplaced(ServletContextAttributeEvent event) {String name = event.getName();Object oldValue = configCache.get(name);Object newValue = event.getValue();configCache.put(name, newValue);System.out.println("配置更新: " + name + " 从 " + oldValue + " 变为 " + newValue);}
}
2. 配置监听器(两种方式)

方式一:注解配置(推荐)

  • 使用 @WebListener 注解,无需额外配置。

方式二:web.xml 配置(传统方式)

<listener><listener-class>com.example.AppConfigListener</listener-class>
</listener>

三、典型应用场景

  1. 动态配置管理
    public void attributeAdded(ServletContextAttributeEvent event) {if ("database.url".equals(event.getName())) {// 更新数据库连接池配置updateDataSource((String) event.getValue());}
    }
    
  2. 全局缓存同步
    public void attributeReplaced(ServletContextAttributeEvent event) {if ("cache.refreshInterval".equals(event.getName())) {// 重新加载缓存refreshCache();}
    }
    
  3. 审计日志记录
    public void attributeRemoved(ServletContextAttributeEvent event) {log.info("敏感配置被移除: " + event.getName());
    }
    

四、注意事项

  1. 线程安全:使用 ConcurrentHashMap 等线程安全结构存储配置,避免多线程问题。
  2. 避免死循环:在监听器方法中不要修改 ServletContext 属性(如再次调用 setAttribute()),否则会触发递归监听。
  3. 性能影响:频繁的属性操作可能影响性能,建议仅在关键配置变更时使用。

五、与其他监听器的区别

监听器类型监听对象典型用途
ServletContextAttributeListenerWeb应用全局属性变化动态配置、全局缓存管理
HttpSessionAttributeListener单个用户会话属性变化用户个性化设置跟踪
ServletRequestAttributeListener单个请求属性变化请求级参数处理(较少使用)

通过 ServletContextAttributeListener,可以实现应用级别的配置热更新、全局状态管理等需求,适用于需要灵活调整应用行为的场景。










4️⃣ 参考 4

ServletContextAttributeListener 是 Java Servlet API 中的一个接口,它允许开发者监听 ServletContext 对象中属性的添加、移除和替换操作。ServletContext 代表整个 Web 应用,通过这个监听器,你可以在属性发生变化时执行相应的逻辑,比如记录日志、更新缓存等。

用法步骤

  1. 创建实现类:编写一个类实现 ServletContextAttributeListener 接口。
  2. 实现接口方法:实现 attributeAddedattributeRemovedattributeReplaced 这三个方法,分别处理属性添加、移除和替换事件。
  3. 配置监听器:可以通过注解或者 web.xml 文件来配置监听器。

示例代码

以下是一个使用 ServletContextAttributeListener 的示例:

import javax.servlet.ServletContextAttributeEvent;
import javax.servlet.ServletContextAttributeListener;
import javax.servlet.annotation.WebListener;// 使用 @WebListener 注解配置监听器
@WebListener
public class MyServletContextAttributeListener implements ServletContextAttributeListener {// 当向 ServletContext 中添加属性时调用@Overridepublic void attributeAdded(ServletContextAttributeEvent event) {String name = event.getName();Object value = event.getValue();System.out.println("ServletContext 中添加了属性: " + name + ",值为: " + value);}// 当从 ServletContext 中移除属性时调用@Overridepublic void attributeRemoved(ServletContextAttributeEvent event) {String name = event.getName();Object value = event.getValue();System.out.println("ServletContext 中移除了属性: " + name + ",值为: " + value);}// 当 ServletContext 中的属性被替换时调用@Overridepublic void attributeReplaced(ServletContextAttributeEvent event) {String name = event.getName();Object oldValue = event.getValue();Object newValue = event.getServletContext().getAttribute(name);System.out.println("ServletContext 中属性 " + name + " 的值从 " + oldValue + " 替换为 " + newValue);}
}

代码解释

  • @WebListener 注解:该注解将 MyServletContextAttributeListener 类注册为一个监听器。
  • attributeAdded 方法:当向 ServletContext 中添加属性时,此方法会被调用,它会输出添加的属性名和属性值。
  • attributeRemoved 方法:当从 ServletContext 中移除属性时,此方法会被调用,它会输出移除的属性名和属性值。
  • attributeReplaced 方法:当 ServletContext 中的属性被替换时,此方法会被调用,它会输出属性名、旧值和新值。

使用 web.xml 配置监听器

如果不使用注解,可以通过 web.xml 文件来配置监听器,示例如下:

<listener><listener-class>com.example.MyServletContextAttributeListener</listener-class>
</listener>

请将 com.example.MyServletContextAttributeListener 替换为你实际的监听器类的全限定名。










5️⃣ 参考 5

ServletContextAttributeListener 是用于监听 ServletContext(即 application 范围)中属性变化的接口,主要监听属性的添加、删除和替换事件。以下是其具体用法:

核心方法

  • attributeAdded(ServletContextAttributeEvent event):当向 ServletContext 添加新属性时触发。可以在该方法中记录属性的名称和值等信息。
  • attributeRemoved(ServletContextAttributeEvent event):当从 ServletContext 删除属性时触发。可以在该方法中记录被删除属性的名称和值等信息。
  • attributeReplaced(ServletContextAttributeEvent event):当替换 ServletContext 中的属性时触发。可以在该方法中记录被替换属性的旧值和新值等信息。

实现步骤

(1)创建监听器类

创建一个类并实现 ServletContextAttributeListener 接口,重写上述三个方法。例如:

import javax.servlet.ServletContextAttributeEvent;
import javax.servlet.ServletContextAttributeListener;public class MyServletContextAttributeListener implements ServletContextAttributeListener {@Overridepublic void attributeAdded(ServletContextAttributeEvent event) {System.out.println("新增属性:" + event.getName() + ",值为:" + event.getValue());}@Overridepublic void attributeRemoved(ServletContextAttributeEvent event) {System.out.println("删除属性:" + event.getName() + ",值为:" + event.getValue());}@Overridepublic void attributeReplaced(ServletContextAttributeEvent event) {System.out.println("替换属性:" + event.getName() + ",旧值为:" + event.getValue() + ",新值为:" + event.getServletContext().getAttribute(event.getName()));}
}
(2)注册监听器

将监听器注册到 Web 应用程序中,可以通过以下几种方式:

  • web.xml 中配置
    <listener><listener-class>com.example.MyServletContextAttributeListener</listener-class>
    </listener>
    
  • 使用 @WebListener 注解(推荐,适用于 Servlet 3.0 及以上版本):
    import javax.servlet.annotation.WebListener;@WebListener
    public class MyServletContextAttributeListener implements ServletContextAttributeListener {// 方法实现与上面相同
    }
    

示例应用

(1)记录属性变化

在监听器中记录 ServletContext 中属性的变化情况,便于后续分析:

import javax.servlet.ServletContextAttributeEvent;
import javax.servlet.ServletContextAttributeListener;public class AttributeLogger implements ServletContextAttributeListener {@Overridepublic void attributeAdded(ServletContextAttributeEvent event) {System.out.println("新增属性:" + event.getName() + ",值为:" + event.getValue());}@Overridepublic void attributeRemoved(ServletContextAttributeEvent event) {System.out.println("删除属性:" + event.getName() + ",值为:" + event.getValue());}@Overridepublic void attributeReplaced(ServletContextAttributeEvent event) {System.out.println("替换属性:" + event.getName() + ",旧值为:" + event.getValue() + ",新值为:" + event.getServletContext().getAttribute(event.getName()));}
}
(2)测试监听器

创建一个 JSP 页面或 Servlet,用于测试 ServletContext 中属性的变化:

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head><title>测试监听器</title>
</head>
<body>
<%application.setAttribute("username", "Tom");application.setAttribute("username", "Jerry");application.removeAttribute("username");
%>
</body>
</html>

通过以上方式,ServletContextAttributeListener 可以在 Web 应用中对 ServletContext 中属性的变化进行监听,从而实现日志记录、数据校验等功能。










6️⃣ 参考 6

ServletContextAttributeListener 是一个接口,用于监听 Servlet 上下文(ServletContext)中属性的变化。通过实现这个接口,可以在属性被添加、移除或替换时执行特定的代码。

步骤:

  1. 创建一个类,实现 ServletContextAttributeListener 接口。
  2. 重写三个方法
    • attributeAdded(ServletContextAttributeEvent event):在属性被添加时调用。
    • attributeRemoved(ServletContextAttributeEvent event):在属性被移除时调用。
    • attributeReplaced(ServletContextAttributeEvent event):在属性被替换时调用。
  3. web.xml 文件中注册监听器,或者使用注解 @WebListener

代码示例:

1. 创建监听器类
import javax.servlet.ServletContextAttributeEvent;
import javax.servlet.ServletContextAttributeListener;
import javax.servlet.annotation.WebListener;@WebListener
public class MyServletContextAttributeListener implements ServletContextAttributeListener {@Overridepublic void attributeAdded(ServletContextAttributeEvent event) {System.out.println("属性添加: " + event.getName() + " = " + event.getValue());// 在这里执行属性添加时的操作}@Overridepublic void attributeRemoved(ServletContextAttributeEvent event) {System.out.println("属性移除: " + event.getName());// 在这里执行属性移除时的操作}@Overridepublic void attributeReplaced(ServletContextAttributeEvent event) {System.out.println("属性替换: " + event.getName() + " = " + event.getValue());// 在这里执行属性替换时的操作}
}
2. 使用 web.xml 注册监听器(可选)

如果你不使用注解,可以在 web.xml 文件中注册监听器:

<listener><listener-class>com.example.MyServletContextAttributeListener</listener-class>
</listener>

解释:

  • @WebListener 注解:这是 Servlet 3.0 及以上版本提供的注解,用于简化监听器的注册。
  • attributeAdded 方法:在属性被添加到上下文时调用,可以在这里进行一些操作。
  • attributeRemoved 方法:在属性从上下文中移除时调用,可以在这里进行一些操作。
  • attributeReplaced 方法:在属性被替换时调用,可以在这里进行一些操作。

通过这种方式,你可以监听 Servlet 上下文中的属性变化,执行相应的逻辑处理。










7️⃣ 参考 7

在这里插入图片描述

ServletContextAttributeListener 使用指南及示例详解

一、核心作用

ServletContextAttributeListener 用于监听 全局应用上下文(ServletContext) 的属性变化事件,包括:

  1. 属性添加attributeAdded
  2. 属性替换attributeReplaced
  3. 属性删除attributeRemoved

典型应用场景

  • 全局配置变更实时响应(如数据库连接池参数更新)
  • 应用启动时加载共享资源(如国际化资源文件)
  • 监控敏感属性操作(如系统密钥被意外修改)

二、实现步骤

1. 创建监听器类

实现 javax.servlet.ServletContextAttributeListener 接口:

import javax.servlet.ServletContextAttributeEvent;
import javax.servlet.ServletContextAttributeListener;
import javax.servlet.annotation.WebListener;@WebListener
public class GlobalConfigMonitor implements ServletContextAttributeListener {@Overridepublic void attributeAdded(ServletContextAttributeEvent event) {String attrName = event.getName();Object value = event.getValue();System.out.printf("[属性添加] 名称: %s | 值: %s | 来源: %s%n", attrName, value, event.getServletContext().getContextPath());// 示例:初始化数据库连接池if ("dbConfig".equals(attrName)) {initDatabaseConnectionPool(value);}}@Overridepublic void attributeReplaced(ServletContextAttributeEvent event) {String attrName = event.getName();Object oldValue = event.getValue();Object newValue = event.getServletContext().getAttribute(attrName);System.out.printf("[属性替换] 名称: %s | 旧值: %s → 新值: %s%n", attrName, oldValue, newValue);// 示例:动态更新日志级别if ("logLevel".equals(attrName)) {updateLogLevel(newValue.toString());}}@Overridepublic void attributeRemoved(ServletContextAttributeEvent event) {String attrName = event.getName();System.out.printf("[属性删除] 名称: %s | 来源应用: %s%n",attrName, event.getServletContext().getContextPath());// 示例:清理缓存if ("cacheConfig".equals(attrName)) {clearGlobalCache();}}private void initDatabaseConnectionPool(Object config) {// 实际初始化逻辑}private void updateLogLevel(String level) {// 动态调整日志级别}private void clearGlobalCache() {// 清理全局缓存}
}
2. 配置方式(二选一)
  • 注解配置(Servlet 3.0+):
    @WebListener // 直接标注类
    
  • XML 配置(兼容旧版本):
    <web-app><listener><listener-class>com.example.GlobalConfigMonitor</listener-class></listener>
    </web-app>
    

三、技术要点解析

1. 事件触发条件
方法触发场景典型用途
attributeAdded调用 ServletContext.setAttribute() 新增属性资源初始化
attributeReplaced调用 ServletContext.setAttribute() 覆盖属性动态配置更新
attributeRemoved调用 ServletContext.removeAttribute()资源释放/状态清理
2. 与 ServletContextListener 的协作
  • 分工对比
    public class ContextLoader implements ServletContextListener {@Overridepublic void contextInitialized(ServletContextEvent sce) {// 应用启动时加载初始配置sce.getServletContext().setAttribute("dbConfig", loadDbConfig());}
    }public class ConfigMonitor implements ServletContextAttributeListener {@Overridepublic void attributeAdded(ServletContextAttributeEvent event) {// 监听后续配置变更}
    }
    
3. 线程安全实践
  • 共享数据管理
    private static final ConcurrentHashMap<String, Lock> configLocks = new ConcurrentHashMap<>();@Override
    public void attributeReplaced(ServletContextAttributeEvent event) {String attrName = event.getName();configLocks.putIfAbsent(attrName, new ReentrantLock());Lock lock = configLocks.get(attrName);lock.lock();try {// 执行需要同步的操作} finally {lock.unlock();}
    }
    

四、进阶应用示例

1. 实现国际化资源热更新
@Override
public void attributeReplaced(ServletContextAttributeEvent event) {if ("i18nResources".equals(event.getName())) {ResourceBundle newBundle = (ResourceBundle) event.getServletContext().getAttribute("i18nResources");reloadLocalizedMessages(newBundle);}
}private void reloadLocalizedMessages(ResourceBundle bundle) {// 更新所有已加载的国际化消息
}
2. 动态数据源切换
@Override
public void attributeAdded(ServletContextAttributeEvent event) {if ("activeDataSource".equals(event.getName())) {DataSource newDS = (DataSource) event.getValue();switchDataSource(newDS);}
}private void switchDataSource(DataSource ds) {// 切换应用主数据源
}

五、注意事项

  1. 作用域范围
    ServletContext全局共享 的,所有用户请求共享同一上下文,需特别注意线程安全问题。

  2. 性能影响
    避免在监听器中执行耗时操作(如同步远程调用),建议异步处理:

    ExecutorService pool = Executors.newFixedThreadPool(4);@Override
    public void attributeAdded(ServletContextAttributeEvent event) {pool.submit(() -> {// 异步处理逻辑});
    }
    
  3. 与 Spring 集成
    若需在监听器中注入 Spring Bean,需通过 WebApplicationContextUtils 获取:

    @Override
    public void attributeAdded(ServletContextAttributeEvent event) {ApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(event.getServletContext());AuditService auditService = ctx.getBean(AuditService.class);auditService.logAttributeChange(event.getName());
    }
    










8️⃣ 参考 8

ServletContextAttributeListener 是 Java Web 应用中用于监听 ServletContext 应用域属性变化的监听器接口,适用于全局属性的增删改事件监控。以下是其核心用法及实践要点:


一、核心方法与作用

  1. attributeAdded(ServletContextAttributeEvent scab)
    触发时机:当属性首次被添加到 ServletContext 时触发。
    典型用途
    • 记录全局属性初始化日志(如加载系统配置参数)
    • 触发依赖该属性的初始化操作(如初始化缓存)

    public void attributeAdded(ServletContextAttributeEvent scab) {String name = scab.getName();  // 获取属性名Object value = scab.getValue(); // 获取属性值System.out.println("全局属性添加:" + name + " → " + value);
    }
    
  2. attributeRemoved(ServletContextAttributeEvent scab)
    触发时机:当属性从 ServletContext 中移除时触发。
    典型用途
    • 清理与属性相关的资源(如关闭数据库连接池)
    • 记录属性删除审计日志

    public void attributeRemoved(ServletContextAttributeEvent scab) {System.out.println("全局属性移除:" + scab.getName());
    }
    
  3. attributeReplaced(ServletContextAttributeEvent scab)
    触发时机:当属性值被修改时触发。
    关键细节
    scab.getValue() 返回 旧值,需通过 scab.getServletContext().getAttribute() 获取新值

    public void attributeReplaced(ServletContextAttributeEvent scab) {Object newValue = scab.getServletContext().getAttribute(scab.getName());System.out.println("属性更新:" + scab.getName() + " → 新值=" + newValue);
    }
    

二、实现与配置步骤

  1. 创建监听器类
    实现接口并重写三个方法,可通过注解或 XML 配置:

    @WebListener  // Servlet 3.0+ 注解方式
    public class ConfigListener implements ServletContextAttributeListener {// 方法实现...
    }
    
  2. XML 配置(传统方式)
    web.xml 中添加:

    <listener><listener-class>com.example.ConfigListener</listener-class>
    </listener>
    

三、典型应用场景

场景实现方式技术要点
属性变更日志监听 attributeAdded/Removed/Replaced 记录属性操作日志结合日志框架(如 Log4j)实现分级日志
全局配置管理在属性修改时触发配置文件重加载(如 appConfig 属性更新后刷新缓存)需处理并发问题,推荐使用原子操作或同步锁
资源同步当数据库连接池参数变更时,动态重建连接池实例通过 scab.getServletContext() 获取应用上下文对象

四、注意事项

  1. 作用域范围
    仅监控 ServletContext 范围内的属性变化,不涉及 HttpSessionServletRequest 的属性。

  2. 执行顺序
    多个属性监听器按配置顺序执行,需避免循环依赖导致的逻辑错误。

  3. 性能影响
    高频属性操作(如频繁修改计数器)可能引发监听器多次触发,建议优化业务逻辑。

  4. 替换事件特殊性
    attributeReplaced 中,event.getValue() 返回旧值,新值需通过 getServletContext().getAttribute() 主动获取。


五、示例代码整合

@WebListener
public class GlobalAttrListener implements ServletContextAttributeListener {@Overridepublic void attributeAdded(ServletContextAttributeEvent event) {System.out.println("[新增] 全局属性: " + event.getName() + " = " + event.getValue());}@Overridepublic void attributeRemoved(ServletContextAttributeEvent event) {System.out.println("[删除] 全局属性: " + event.getName());}@Overridepublic void attributeReplaced(ServletContextAttributeEvent event) {ServletContext context = event.getServletContext();String name = event.getName();Object newValue = context.getAttribute(name);System.out.println("[更新] 全局属性: " + name + " → 新值=" + newValue);}
}

通过合理使用 ServletContextAttributeListener,开发者可以实现对全局属性的全生命周期监控,提升应用的可维护性和业务灵活性。具体实现细节可参考 Servlet 官方文档 及示例代码。










9️⃣ 参考 9

ServletContextAttributeListener 是 Java Web 开发中用于监听 ServletContext 属性(即应用级属性)的增删改事件的接口。它允许你在属性被添加、删除或替换时执行自定义逻辑(如监控配置变化、记录日志等)。以下是其核心用法:


核心方法

  1. attributeAdded(ServletContextAttributeEvent event)

    • 当向 ServletContext 添加新属性时触发。
    • 参数 event 可获取属性名、新值和上下文对象。
    • 典型用途:记录属性添加事件、验证属性合法性。
  2. attributeRemoved(ServletContextAttributeEvent event)

    • 当从 ServletContext 删除属性时触发。
    • 参数 event 可获取属性名、旧值和上下文对象。
    • 典型用途:记录属性删除事件、清理关联资源。
  3. attributeReplaced(ServletContextAttributeEvent event)

    • ServletContext 中的属性被替换(即通过相同名称更新值)时触发。
    • 参数 event 可获取属性名、旧值和新值。
    • 典型用途:监控配置变更、同步更新其他组件。

使用步骤

  1. 实现接口
    创建一个类实现 ServletContextAttributeListener 接口,并重写三个方法:

    import javax.servlet.ServletContextAttributeEvent;
    import javax.servlet.ServletContextAttributeListener;
    import javax.servlet.annotation.WebListener;@WebListener // 使用注解注册监听器(Servlet 3.0+)
    public class MyContextAttributeListener implements ServletContextAttributeListener {@Overridepublic void attributeAdded(ServletContextAttributeEvent event) {System.out.println("属性添加:" + event.getName() + " = " + event.getValue());// 监控或记录新增属性}@Overridepublic void attributeRemoved(ServletContextAttributeEvent event) {System.out.println("属性删除:" + event.getName() + "(旧值:" + event.getValue() + ")");// 清理或记录删除操作}@Overridepublic void attributeReplaced(ServletContextAttributeEvent event) {System.out.println("属性替换:" + event.getName() + "(旧值:" + event.getValue() + " → 新值:" + event.getNewValue() + ")");// 处理配置更新(如刷新缓存)}
    }
    
  2. 配置监听器

    • 方式 1:通过 @WebListener 注解(推荐,无需额外配置)。
    • 方式 2:在 web.xml 中声明
      <listener><listener-class>com.example.MyContextAttributeListener</listener-class>
      </listener>
      

典型应用场景

  1. 监控配置变化
    如全局配置文件(如数据库地址)通过属性动态更新时,触发重新加载逻辑:

    public void attributeReplaced(ServletContextAttributeEvent event) {if ("DB_URL".equals(event.getName())) {System.out.println("数据库地址已更新,重新连接...");// 执行数据库重连操作}
    }
    
  2. 记录操作日志
    记录所有属性的增删改事件,便于调试或审计。

  3. 同步资源状态
    当某个全局资源(如缓存、连接池)的配置属性被修改时,自动更新相关组件。


注意事项

  • 获取属性信息
    通过 event.getName() 获取属性名,event.getValue() 获取旧值(attributeReplaced 中可通过 event.getNewValue() 获取新值)。
  • 线程安全
    ServletContext 的属性操作可能在多线程下发生,需确保对共享资源的访问安全。
  • ServletContextListener 的区别
    • ServletContextListener 监听应用的启动和关闭。
    • ServletContextAttributeListener 仅监听 属性 的增删改事件。

通过 ServletContextAttributeListener,你可以精准控制和监控应用级属性的变化,确保系统配置的实时性和一致性。










🔟 参考 10

ServletContextAttributeListener用于监听ServletContext(application)范围内属性的变化,其用法主要包括以下几个方面:

  1. 接口定义

    • ServletContextAttributeListener是一个接口,包含三个方法:attributeAdded(ServletContextAttributeEvent event)attributeRemoved(ServletContextAttributeEvent event)attributeReplaced(ServletContextAttributeEvent event)[1][2]。
  2. 实现类

    • 创建一个类实现ServletContextAttributeListener接口,并重写上述三个方法。例如,可以创建一个名为MyServletContextAttributeListener的类,并在其中实现attributeAddedattributeRemovedattributeReplaced方法[1][5]。
  3. 注册监听器

    • web.xml文件中配置<listener>元素来注册监听器。指定监听器的类名,以便Servlet容器在启动或关闭Web应用时能够调用相应的方法[4]。
    • 在Spring Boot等现代Java框架中,可以通过使用注解(如@WebListener)来简化配置,无需在web.xml中进行配置[1][2][5]。
  4. 应用场景举例

    • 资源管理:在添加属性时分配必要的资源(如数据库连接、文件句柄等),并在删除属性时释放这些资源,以防止资源泄漏[1]。
    • 权限验证:在添加或修改属性时进行用户身份验证和权限检查,确保只有合法的用户才能访问受保护的资源[1]。
    • 日志记录:记录属性的添加、删除和替换时间等信息,以便进行审计和故障排查[1]。
    • 缓存更新:当某个关键属性被修改时,触发缓存更新逻辑,以保持系统数据的一致性[1]。

综上所述,ServletContextAttributeListener为开发者提供了一个方便的机制来监听ServletContext范围内属性的变化,通过合理利用这一监听器,可以增强Web应用的功能和可维护性。



















相关文章:

ServletContextAttributeListener 的用法笔记250417

ServletContextAttributeListener 的用法笔记250417 以下是关于 ServletContextAttributeListener 的用法详解&#xff0c;涵盖核心方法、实现场景、注意事项及最佳实践&#xff0c;帮助您有效监听应用级别属性&#xff08;ServletContext&#xff09;的变化&#xff1a; 1. 核…...

iptables 防火墙

目录 熟悉Linux防火墙的表&#xff0c;链结构 理解数据包匹配的基本流程 学会编写iptables规则 前言 在当今信息化时代,网络安全已成为企业和个人不可忽视的重要议题。随着网络攻击手段的不断升级,构建一个坚固的网络安全防线显得尤为迫切。在Linux系统中,iptables作为一款…...

【厦门大学】DeepSeek大模型及其企业应用实践

DeepSeek大模型及其企业应用实践 前言1. 大模型&#xff1a;人工智能的前沿1.1 大模型的概念1.2 大模型的发展历程1.3 人工智能与大模型的关系1.4 大模型的分类 2. 大模型产品2.1 国外的大模型产品2.2 国内的大模型产品2.3 主流大模型“幻觉”评测 3. 大模型的行业应用3.1 自然…...

解锁智能制造:PLC远程下载如何让设备运维效率提升10倍?

一、2025年远程运维的三大变革驱动力 政策强制&#xff1a; 欧盟CE新规要求&#xff1a;2025年起工业设备必须具备远程审计接口 中国等保2.0&#xff1a;工业控制系统远程访问需达到三级防护 技术成熟&#xff1a; 5G专网边缘计算实现ms级响应 算法自动诊断PLC程序异常&#x…...

卷积神经网络CNN(李宏毅)

目录 怎么把一张影响当成一个模型输入&#xff1f; 同样的 pattern出现在图片不同的位置。 第三个问题&#xff1a;Pooling&#xff1a; 阿尔法Go是怎么下围棋的&#xff1a; CNN不能处理的问题 CNN专门用在影像辨识方面 怎么把一张影响当成一个模型输入&#xff1f; 一张…...

URL / GET请求 中文UTF-8编码JS转化

以长颈鹿为例 decodeURIComponent 将编码转为中文 encodeURIComponent 会对整个参数字符串转义&#xff08;包括 :// 等符号&#xff09;。 encodeURI 仅转义非合法 URL 字符&#xff08;不转义 :/?& 等保留字符&#xff09;。 decodeURIComponent("%E9%95%BF%E9…...

Flink 内部通信底层原理

Flink 集群内部节点之间的通信是用 Akka 实现,比如 JobManager 和 TaskManager 之间的通信。而 operator 之间的数据传输是用 Netty 实现。 RPC 框架是 Flink 任务运行的基础,Flink 整个 RPC 框架基于 Akka 实现。 一、相关概念 RPC(Remote Procedure Call) 概念 定义:…...

async-profiler火焰图找出耗CPU方法

事情起于开发应用对依赖的三方包&#xff08;apache等等&#xff09;进行了升级后&#xff08;主要是升级spring&#xff09;&#xff0c;CPU的使用率较原来大幅提升&#xff0c;几个应用提升50%-100%。 查找半天&#xff0c;对比每次版本的cpu火焰图&#xff0c;看不出有什么…...

深入理解Qt状态机的应用

深入理解Qt状态机的应用 Chapter1 深入理解Qt状态机的应用&#xff08;一&#xff09;什么是有限状态机&#xff1f;状态机的组成应用示例交通信号控制灯系统简单在线购物流程系统 Qt状态机框架Qt状态机框架组成常用接口说明 应用示例源码 Chapter2 深入理解Qt状态机的应用&…...

Python入门安装和语法基础

1.Python简介 Python是解释型语言, ython就为我们提供了非常完善的基础代码库&#xff0c;覆盖了网络、文件、GUI、数据库、文本等大量内容&#xff0c;被形象地称作“内置电池&#xff08;batteries included&#xff09;”。用Python开发&#xff0c;许多功能不必从零编写&am…...

Windows 图形显示驱动开发-WDDM 1.2功能—Windows 8 中的 DirectX 功能改进(四)

一、无覆盖和放弃 在基于磁贴的延迟呈现 (TBDR) 体系结构上呈现内容&#xff1a; Direct3D 11.1 中的呈现目标现在可以使用一组新的资源 API 来支持放弃行为。 开发人员必须了解此功能&#xff0c;并调用额外的 Discard () 方法&#xff0c;以在 TBDR 体系结构 (更高效地运行…...

如何分析服务器日志以追踪黑客攻击行为

分析服务器日志是追踪黑客攻击行为的关键手段。通过系统性地检查日志文件&#xff0c;可以发现异常访问模式、入侵痕迹和后门活动。以下是详细的日志分析方法&#xff1a; 一、重点日志文件定位 Web服务器日志 Nginx: /var/log/nginx/access.log&#xff08;访问日志&#xff0…...

React 对state进行保留和重置

对 state 进行保留和重置 各个组件的 state 是各自独立的。根据组件在 UI 树中的位置&#xff0c;React 可以跟踪哪些 state 属于哪个组件。你可以控制在重新渲染过程中何时对 state 进行保留和重置。 开发环境&#xff1a;Reacttsantd 学习内容 React 何时选择保留或重置状态…...

EmbeddingBag介绍与案例

我们可以用一个具体的例子来说明 EmbeddingBagCollection 的核心作用和它如何处理用户特征。假设我们的用户特征包括 “item_id” 和 “cate_id” 两个字段&#xff0c;每个字段都有各自的离散取值&#xff0c;也就是一些整数 ID。为了让模型能处理这些离散数据&#xff0c;我们…...

css button 点击效果

<!DOCTYPE html> <html lang"zh-CN"><head><meta charset"UTF-8"><title>button点击效果</title><style>#container {display: flex;align-items: center;justify-content: center;}.pushable {position: relat…...

Missashe考研日记-day22

Missashe考研日记-day22 1 专业课408 学习时间&#xff1a;3h学习内容&#xff1a; 先把昨天关于进程调度的课后习题做了&#xff0c;然后花了挺长时间预习OS的最最最最重要的一部分——同步与互斥问题&#xff0c;这部分大二上课的时候就懵懵懂懂的&#xff0c;得认真再领悟…...

二十、FTP云盘

1、服务端 #include <stdio.h> #include <string.h> #include <stdlib.h> #include <sys/types.h> #include <unistd.h> #include <sys/types.h> /* See NOTES */ #include <sys/socket.h> #include <netinet/in.h>…...

SVM-RF回归预测matlab代码

数据为Excel股票预测数据。 数据集划分为训练集、验证集、测试集,比例为8&#xff1a;1&#xff1a;1 模块化结构: 代码将整个流程模块化&#xff0c;使得代码更易于理解和维护。不同功能的代码块被组织成函数或者独立的模块&#xff0c;使得代码逻辑清晰&#xff0c;结构化程…...

Lombok @Builder 注解的进阶玩法:自定义 Getter/Setter 方法全攻略

大家好呀&#xff01;&#x1f44b; 今天我们来聊聊 Java 开发中超级实用的 Lombok 库&#xff0c;特别是它的 Builder 注解。很多小伙伴都用过 Builder 来简化对象的创建&#xff0c;但你们知道吗&#xff1f;当我们需要自定义 getter/setter 方法时&#xff0c;Builder 也能玩…...

C++每日训练 Day 16:构建 GUI 响应式信号机制(面向初学者)

&#x1f4d8; 本篇我们将结合之前的 SignalHub 与 Dispatcher 机制&#xff0c;构建一个适合 GUI 场景的响应式信号系统。以按钮点击为例&#xff0c;构建一个跨线程安全的事件响应系统&#xff0c;配合协程挂起/恢复&#xff0c;让 UI 编程也能更优雅易读。本篇以通俗方式讲解…...

HCIP(OSPF )(2)

OSPF 公共报文头部 版本&#xff08;8bit&#xff09;&#xff1a;目前常用版本为 2&#xff0c;用于标识 OSPF 协议版本。不同版本在功能特性和报文格式上可能存在差异&#xff0c;高版本通常会修复旧版本的漏洞、扩展功能&#xff0c;如支持更多类型的网络拓扑、增强安全性等…...

zynq7020 ubuntu_base 跟文件系统

整体流程 制作 ubuntu_base 镜像运行 petalinux 构建的 ramdisk 系统用 ramdisk 系统把 ubuntu_base 镜像烧录到 emmc从 emmc 跟文件系统 启动内核 制作 ubuntu_base 镜像 制作 ubuntu_base 镜像 sudo apt-get install qemu-user-static # 安装 q…...

51、Spring Boot 详细讲义(八) Spring Boot 与 NoSQL

3、 Elasticsearch 集成 3.1 Elasticsearch 概述 3.1.1 Elasticsearch 的核心概念 Elasticsearch 是一个开源的分布式搜索引擎,主要用于实时数据检索和分析。它的核心功能包括全文检索、结构化查询和分析大规模数据。 分布式搜索引擎: Elasticsearch 将数据分布存储在多个…...

什么是分库分表?

分库分表是一种数据库的分布式架构设计策略&#xff0c;以下是详细介绍&#xff1a; 概念 • 随着互联网的发展&#xff0c;数据量呈爆炸式增长&#xff0c;单个数据库服务器可能难以应对海量数据的存储和访问压力。分库分表就是将原本庞大的数据库拆分成多个小的数据库&#…...

如何让别人访问到自己本地项目?使用内网穿透工具简单操作下实现公网连接!

本地搭建服务器的系统项目网络地址&#xff0c;在没有公网IP使用的情况下&#xff0c;如何让局域网外别人访问到自己本地网站和应用呢&#xff1f;这里介绍一种通用的内网发布公网访问&#xff0c;且简便操作的内网穿透实现方法。 一、什么是内网穿透&#xff1f; 1. 先了解内…...

第一篇:linux之虚拟环境与centos安装

第一篇&#xff1a;linux之虚拟环境与centos安装 文章目录 第一篇&#xff1a;linux之虚拟环境与centos安装一、vmware安装二、centos安装1、centos虚拟环境安装2、centos操作系统配置3、常见问题解决 一、vmware安装 我们想要运行linux&#xff0c;需要先安装一个虚拟软件&am…...

Redis List 的详细介绍

Redis List 的详细介绍 以下是 Redis List 的详细介绍&#xff0c;从基础命令、内部编码和使用场景三个维度展开&#xff1a; 一、基础命令 Redis List 支持双向操作&#xff08;头尾插入/删除&#xff09;&#xff0c;适用于队列、栈等场景&#xff0c;以下是核心命令分类&a…...

docker占用磁盘100%

1. 立即清理方案 快速清理命令 bash 复制 # 停止Docker服务 sudo systemctl stop docker# 清理所有无用数据&#xff08;包括未使用的镜像、容器、网络和卷&#xff09; sudo docker system prune -a --volumes# 重启Docker sudo systemctl start docker 手动清理overlay2…...

20250417-vue-条件插槽

有时候我们需要根据内容是否被传入了插槽来渲染某些内容。 你可以结合使用 $slot 属性与 v-if 来实现。 在下面的示例中&#xff0c;我们定义了一个卡片组件&#xff0c;它拥有三个条件插槽&#xff1a;header、footer 和 default。当 header、footer 或 default 的内容存在时…...

【Unity】UI点击事件处理器

目录 前言脚本 前言 在开发过程中&#xff0c;经常需要监听UI的点击事件&#xff0c;这里我给大家整理一下&#xff0c;脚本直接挂在需要监听的节点上即可。 脚本 using UnityEngine; using UnityEngine.Events; using UnityEngine.EventSystems;namespace GameLogic {/// &…...

阿里云服务器的docker环境安装nacos--实践

阿里云服务器的docker环境安装nacos–实践 前提先安装mysql数据库&#xff0c;mysql中创建nacos所需的表以下为阿里云服务器docker环境安装&#xff0c;需在安全组开放8848端口 1. 拉取nacos-server镜像 //最新版本nacos docker pull nacos/nacos-server//或者指定nacos版本…...

每日算法-链表(23.合并k个升序链表、25.k个一组翻转链表)

一.合并k个升序链表 1.1题目描述 1.2题解思路 解法一&#xff1a;小根堆 我们可以先定义一个小根堆&#xff0c;将k个指针的头结点如堆&#xff0c;每次取堆顶元素尾插到newhead中&#xff0c;然后再pop()&#xff0c;接着push堆顶原来堆顶元素的下一个节点 重点分析&#…...

数据结构——反射、枚举以及lambda表达式

1. 反射 Java的反射&#xff08;reflection&#xff09;机制是在运⾏时检查、访问和修改类、接⼝、字段和⽅法的机制&#xff1b;这种动态获取信息以及动态调⽤对象⽅法的功能称为java语⾔的反射&#xff08;reflection&#xff09;机制。 用途 1. 框架开发 2. 注解处理 3.…...

深入理解 HTML5 Web SQL 数据库:用法、现状与替代方案

一、引言 在 Web 开发的领域中,客户端存储一直是一个关键的话题。HTML5 带来了多种客户端存储的解决方案,其中 Web SQL 数据库曾经是一个备受关注的选项。尽管如今它已被废弃,但了解其原理、使用方法以及为何被替代,对于 Web 开发者来说仍然具有重要的意义。本文将深入探讨…...

系统架构设计(一):UML与软件架构

什么是系统架构设计&#xff1f; 系统架构设计是对系统高层结构和行为的描述&#xff0c;包括&#xff1a; 系统的各个模块&#xff08;组件&#xff09;模块之间的交互方式数据流动、控制流动技术选型与部署策略 系统架构常见的风格有&#xff1a; 分层架构&#xff08;La…...

极狐GitLab 外部流水线验证功能解读

极狐GitLab 是 GitLab 在中国的发行版&#xff0c;关于中文参考文档和资料有&#xff1a; 极狐GitLab 中文文档极狐GitLab 中文论坛极狐GitLab 官网 外部流水线验证 (BASIC SELF) 您可以使用外部服务在创建流水线之前进行验证。 极狐GitLab 发送一个 POST 请求到外部服务的…...

MCP和A2A是什么?

MCP和A2A是什么&#xff1f; MCP&#xff08;Model-Connect Protocol&#xff09;和A2A&#xff08;Agent-to-Agent&#xff09;协议逐渐成为行业关注的焦点。这两个协议分别由Anthropic和谷歌推出&#xff0c;旨在提升智能体与外部工具、数据源及API资源的连接效率&#xff0c…...

CNN卷积神经网络

一、什么是卷积神经网络&#xff08;CNN&#xff09; CNN&#xff08;卷积神经网络&#xff09;是一种专门用于处理图像的神经网络&#xff0c;尤其在图像识别任务中表现出色&#xff0c;例如识别手写数字。它通过多层结构逐步提取图像特征&#xff0c;最终输出识别结果。与传…...

生物信息学技能树(Bioinformatics)与学习路径

李升伟 整理 生物信息学是一门跨学科领域&#xff0c;涉及生物学、计算机科学以及统计学等多个方面。以下是关于生物信息学的学习路径及相关技能的详细介绍。 一、基础理论知识 1. 生物学基础知识 需要掌握分子生物学、遗传学、细胞生物学等相关概念。 对基因组结构、蛋白质…...

Obsidian无门槛简明教程

Obsidian简明教程 Markdown基本语法基本码字标题换行段落引用分割线代码块链接带名字的链接超链接插入图片 强调语法加粗斜体删除线高亮 列表有序列表无序列表任务列表 Obsidian核心用法软件基本使用安装仓库文件夹笔记编辑与查看 资源 核心插件双链标签 三方插件Various Compl…...

常用 Git 命令详解

Git 是一个强大的版本控制工具&#xff0c;广泛用于软件开发和团队协作中。掌握 Git 命令可以帮助开发者更高效地管理代码版本和项目进度。本文将介绍一些常用的 Git 命令&#xff0c;并提供示例以帮助你更好地理解和应用这些命令。 目录 常用命令 git clonegit stashgit pul…...

【HDFS入门】HDFS与Hadoop生态的深度集成:与YARN、MapReduce和Hive的协同工作原理

目录 引言 1 HDFS核心架构回顾 2 HDFS与YARN的集成 3 HDFS与MapReduce的协同 4 HDFS与Hive的集成 4.1 Hive架构与HDFS交互 4.2 Hive数据组织 4.3 Hive查询执行流程 5 HDFS在生态系统中的核心作用 6 性能优化实践 7 总结 引言 在大数据领域&#xff0c;Hadoop生态系统…...

多路由器通过三层交换机互相通讯(单臂路由+静态路由+默认路由版),通过三层交换机让pc端相互通讯

多路由器通过三层交换机互相通讯&#xff08;单臂路由静态路由默认路由版&#xff09; 先实现各个小框框里能够互通 哇咔 交换机1&#xff08;二层交换机,可看配置单臂路由的文章) Switch>en Switch#conf t Switch(config)#int f0/1 Switch(config-if)#switchport access…...

电控---CMSIS概览

1. CMSIS库简介 CMSIS&#xff08;Cortex Microcontroller Software Interface Standard&#xff0c;Cortex微控制器软件接口标准&#xff09;是由ARM公司开发的一套标准化软件接口&#xff0c;旨在为基于ARM Cortex-M系列处理器&#xff08;如Cortex-M0/M0/M3/M4/M7/M33等&am…...

2025.04.17【Stacked area】| 生信数据可视化:堆叠区域图深度解析

文章目录 生信数据可视化&#xff1a;堆叠区域图深度解析堆叠面积图简介为什么使用堆叠面积图如何使用R语言创建堆叠面积图安装和加载ggplot2包创建堆叠面积图的基本步骤示例代码 解读堆叠面积图堆叠面积图的局限性实际应用案例示例&#xff1a;基因表达量随时间变化 结论 生信…...

XSS之同源、跨域、内容安全策略

一、什么是同源策略 HTML的同源策略是浏览器的一个重要的安全机制&#xff0c;它用于限制一个源的网页如何与另一个源的资源进行交互&#xff0c;以此来减少夸站脚本攻击(XSS)和跨站请求伪造(CSRF)等安全风险。 同源的定义 若两个URL的协议&#xff08;protocol&#xff09;、…...

十三、系统设计

一、前言 二、架构设计概念 三、架构风格 四、面向服务的架构 五、微服务 六、MDA 七、软件界面设计 八、软件设计的构成 九、结构化设计 十、面向对象设计内容提要 十一、面向对象设计原则 十二、架构模式、设计模式与惯用法...

HTTP 2.0 协议特性详解

1. 使用二进制协议&#xff0c;简化传输的复杂性&#xff0c;提高了效率 2. 支持一个 TCP 链接发起多请求&#xff0c;移除 pipeline HTTP/2 移除了 HTTP/1.1中的管道化&#xff08;pipeline&#xff09;机制&#xff0c;转而采用多路复用&#xff08;Multiplexing&#xff0…...

MySQL数据备份

一&#xff0c;为什么要进行数据备份 备份&#xff1a;能够防止由于机械故障以及人为误操作带来的数据丢失&#xff0c;例如将数据库文件保存在了其它地方。冗余&#xff1a; 数据有多份冗余&#xff0c;但不等备份&#xff0c;只能防止机械故障带来的数据丢失&#xff0c;例如…...

【Ai】CherryStudio 详细使用:本地知识库、MCP服务器

一、CherryStudio 介绍 Cherry Studio 是一款集多模型对话、知识库管理、AI 绘画、翻译等功能于一体的全能 AI 助手平台。 Cherry Studio 高度自定义的设计、强大的扩展能力和友好的用户体验&#xff0c;使其成为专业用户和 AI 爱好者的理想选择。无论是零基础用户还是开发者&…...