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

Java 拦截器完全指南:原理、实战与最佳实践

一、引言

拦截器的基本概念

在现代 Java Web 开发中,拦截器(Interceptor)是一种用于在请求处理前后插入自定义逻辑的机制。简单来说,它是一种“横切逻辑处理器”,可以用来对请求进行预处理、后处理,甚至终止请求的继续执行。

它通常用于对控制器(Controller)方法进行增强,而不需要修改控制器本身的代码,实现逻辑与业务的解耦。

类似于门卫,它能在用户请求进入“房间”(Controller)之前或之后,进行安检、打卡或记录日志等操作。


拦截器的应用场景

拦截器在实际开发中的应用非常广泛,尤其在Spring MVC项目中几乎是标配工具,常见使用场景包括:

  • 权限校验:验证用户是否已登录,是否有访问某接口的权限。

  • 日志记录:记录请求的路径、方法、参数和响应信息,便于后续问题排查。

  • 性能监控:计算接口的执行耗时,帮助开发者发现性能瓶颈。

  • 请求预处理:如统一设置编码、参数转换、接口签名校验等。

  • 响应后处理:如在响应返回前追加通用信息或处理返回结构。


与过滤器(Filter)和 AOP 的对比

特性Filter(过滤器)Interceptor(拦截器)AOP(面向切面编程)
所属层级Servlet 规范Spring MVCSpring AOP
拦截范围所有请求(包括静态资源)控制器请求(Handler)任意方法(基于切点)
使用场景通用处理,如编码设置、日志权限、登录校验等业务层处理日志、事务、缓存、异常捕捉等
配置方式web.xml 或注解Spring 配置类中注册注解(@Aspect)、配置切面
拦截粒度粒度较粗,Servlet 前粒度适中,Handler 层粒度最细,可作用于任意方法

简而言之:

  • Filter 更底层,作用于整个请求生命周期;

  • Interceptor 更贴近业务逻辑,专注于控制器调用;

  • AOP 最灵活,适用于各种“横切关注点”逻辑处理。


二、Java 中拦截器的常见实现方式 🛠️

Java 中的拦截器可以通过多种方式实现,不同技术栈和场景有不同的最佳实践。以下是三种最常见的实现方式:


1️⃣ Servlet 拦截器(Filter)

⚙️ 工作原理

Filter 是 Servlet 规范定义的一种机制,属于 Java EE 标准,在请求进入 Servlet 前或响应返回客户端前进行拦截。它通常用在 Web 层处理一些通用逻辑,如设置编码、日志记录、安全控制等。

🔄 生命周期

Filter 生命周期如下:

  1. 初始化:容器启动时调用 init()

  2. 请求处理:每次请求通过时执行 doFilter()

  3. 销毁:容器关闭时调用 destroy()

💡 示例代码:记录请求日志
@WebFilter(urlPatterns = "/*")
public class LogFilter implements Filter {@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)throws IOException, ServletException {HttpServletRequest req = (HttpServletRequest) request;System.out.println("请求路径: " + req.getRequestURI());chain.doFilter(request, response);}
}

📌 适合用于:编码统一、访问统计、跨域处理等通用任务。


2️⃣ Spring MVC 拦截器(HandlerInterceptor)

📑 接口简介

Spring MVC 提供了 HandlerInterceptor 接口,以及一个简化实现类 HandlerInterceptorAdapter(从 Spring 5.3 起已废弃,推荐直接实现接口)。

🔍 方法解析
  • preHandle():控制器方法调用前执行,可用于权限校验(返回 false 则请求中断);

  • postHandle():控制器执行后、视图渲染前调用;

  • afterCompletion():整个请求完成后调用(如资源清理、异常处理等)。

🔐 示例代码:权限校验
public class AuthInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)throws Exception {Object user = request.getSession().getAttribute("user");if (user == null) {response.sendRedirect("/login");return false;}return true;}
}

🔧 注册拦截器:

@Configuration
public class WebConfig implements WebMvcConfigurer {@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new AuthInterceptor()).addPathPatterns("/**").excludePathPatterns("/login", "/static/**");}
}

📌 适合用于:登录校验、权限控制、接口限流等业务逻辑相关场景。


3️⃣ AOP(面向切面编程)方式的拦截

🧵 基于注解的切面拦截(@Aspect)

AOP 是 Spring 提供的一种强大机制,用于将“横切逻辑”(如日志、事务、缓存)与业务代码彻底解耦。只要是 Spring 管理的 Bean 方法,都可以通过 AOP 拦截。

🎯 Pointcut 表达式简介
  • @Pointcut("execution(* com.example.service..*(..))"):拦截 service 包及子包中所有方法;

  • @Before / @After / @Around:分别在方法执行前、后或整个过程中插入逻辑。

📝 示例代码:统一日志处理
@Aspect
@Component
public class LogAspect {@Pointcut("execution(* com.example.controller..*(..))")public void controllerMethods() {}@Before("controllerMethods()")public void logBefore(JoinPoint joinPoint) {System.out.println("访问方法: " + joinPoint.getSignature().toShortString());System.out.println("参数: " + Arrays.toString(joinPoint.getArgs()));}
}

📌 适合用于:日志、事务、异常处理、性能监控等通用横切需求。


三、自定义拦截器 ✍️

在实际项目中,默认提供的拦截器功能可能无法完全满足特定需求,这时我们就需要自定义拦截器来处理特定的业务逻辑,比如登录校验、接口签名验证、敏感操作审计等。

下面我们一步一步来实现一个自定义拦截器 👇


1️⃣ 如何编写自己的拦截器类

在 Spring MVC 中,自定义拦截器只需要实现 HandlerInterceptor 接口,并重写其中的方法即可。

public class CustomInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {System.out.println("🚦 请求开始 - URL: " + request.getRequestURI());return true; // 返回 false 则中断请求}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response,Object handler, ModelAndView modelAndView) throws Exception {System.out.println("📦 控制器处理完成");}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response,Object handler, Exception ex) throws Exception {System.out.println("✅ 请求完成");}
}

📌 Tip:你可以只实现 preHandle(),其他两个方法不实现也没问题。


2️⃣ 如何注册拦截器

要让 Spring 识别并使用我们自定义的拦截器,需要通过实现 WebMvcConfigurer 接口中的 addInterceptors() 方法进行注册。

@Configuration
public class WebConfig implements WebMvcConfigurer {@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new CustomInterceptor()).addPathPatterns("/**")      // 拦截所有请求.excludePathPatterns("/login", "/error"); // 排除登录和错误页面}
}

3️⃣ 配置拦截路径(include / exclude)

Spring 提供了灵活的路径匹配方式:

  • addPathPatterns():指定要拦截的路径(支持 /**/api/** 等通配符);

  • excludePathPatterns():指定不拦截的路径,如静态资源、登录页面等。

✅ 示例配置:
registry.addInterceptor(new AuthInterceptor()).addPathPatterns("/admin/**", "/user/**")     // 只拦截 /admin 和 /user 开头的请求.excludePathPatterns("/user/login", "/static/**"); // 登录接口和静态资源不拦截

这让你可以精确控制哪些接口需要“守门”,哪些接口可以直接放行


📌 小结:

  • 自定义拦截器灵活强大,能精准控制请求流程;

  • 注册时配置好路径规则,避免误拦(如静态资源、登录页);

  • 通常与登录校验、行为日志、安全审计等结合使用,提升系统健壮性。

四、拦截器执行顺序与链式调用 🔗

在实际开发中,一个项目往往不止一个拦截器。比如,你可能同时使用了登录拦截器、日志拦截器、接口限流拦截器等。**这些拦截器是如何协同工作的?它们的执行顺序如何确定?中途终止又会发生什么?**下面我们来逐一讲解 👇


1️⃣ 多个拦截器的执行顺序

Spring MVC 中的拦截器是按注册顺序组成拦截链的。假设你注册了三个拦截器:

registry.addInterceptor(new AInterceptor());
registry.addInterceptor(new BInterceptor());
registry.addInterceptor(new CInterceptor());

执行顺序如下:

  • preHandle():A → B → C

  • postHandle():C → B → A

  • afterCompletion():C → B → A

🧠 记忆小技巧

preHandle 正序入场,postHandleafterCompletion 倒序退场,就像调用栈的压栈和出栈操作。


2️⃣ 如何控制执行顺序 🧭

有两种主要方式可以控制拦截器的执行顺序:

✅ 方式一:注册顺序决定先后

Spring MVC 默认按照 addInterceptor() 的顺序执行拦截器链。这是最常用也最直观的方法。

🏷️ 方式二:使用 @Order 注解(对 Bean 注册时生效)

如果你通过 Spring 的方式将拦截器注入(比如 @Bean@Component),可以使用 @Order 指定优先级:

@Component
@Order(1)
public class FirstInterceptor implements HandlerInterceptor {// 优先执行
}

值越小,优先级越高。注意,@Order 只在 Bean 自动注入时生效,手动 new 的方式无效。


3️⃣ 拦截器链中断的处理逻辑 🛑

每个 preHandle() 方法都返回一个 boolean 值:

  • 返回 true:继续执行下一个拦截器或控制器方法;

  • 返回 false拦截链立即中断,后续拦截器不会被执行,控制器方法也不会被调用。

例如:

@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {if (!isAuthorized(request)) {response.sendRedirect("/unauthorized");return false; // 中断链路}return true;
}

🔔 注意事项:

  • 中断后,只有当前拦截器的 afterCompletion() 会执行,其他已注册但未执行的拦截器方法将被跳过。

  • 可以通过 response 返回错误提示或重定向,防止继续请求控制器。


📌 小结:

  • 拦截器执行顺序 = 注册顺序;

  • 可通过 @Order 控制优先级(仅限 Bean 注册);

  • 一旦有拦截器返回 false,链路即刻中断,防止后续逻辑执行。

五、拦截器实战案例 🧪

这一部分,我们围绕几个典型的业务需求,手把手展示拦截器的实际用法。这些场景非常常见,99% 的项目都能用得上


1️⃣ 登录鉴权拦截器 🔐

目的:判断用户是否已登录,未登录则重定向至登录页。

public class LoginInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)throws Exception {Object user = request.getSession().getAttribute("loginUser");if (user == null) {response.sendRedirect("/login");return false; // 阻止未登录请求继续向下执行}return true;}
}

📌 常配合 Session、Token 或 Spring Security 使用。


2️⃣ 接口防刷(限流)拦截器 🚦

目的:防止接口被频繁调用(比如验证码接口、短信发送等)。

public class RateLimitInterceptor implements HandlerInterceptor {private Map<String, Long> visitMap = new ConcurrentHashMap<>();@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {String ip = request.getRemoteAddr();long now = System.currentTimeMillis();Long lastVisit = visitMap.get(ip);if (lastVisit != null && now - lastVisit < 2000) {response.setStatus(429); // Too Many Requestsreturn false;}visitMap.put(ip, now);return true;}
}

📌 建议结合 Redis 做分布式限流,高并发更稳!


3️⃣ 日志跟踪(Trace ID)拦截器 🧾

目的:为每个请求生成唯一标识 TraceId,便于链路追踪和日志排查。

public class TraceInterceptor implements HandlerInterceptor {private static final ThreadLocal<String> TRACE_ID_HOLDER = new ThreadLocal<>();@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {String traceId = UUID.randomUUID().toString();TRACE_ID_HOLDER.set(traceId);MDC.put("traceId", traceId); // 与日志框架整合System.out.println("Trace ID: " + traceId);return true;}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response,Object handler, Exception ex) {TRACE_ID_HOLDER.remove();MDC.remove("traceId");}
}

📌 搭配 Logback、ELK 可实现完整请求链路分析。


4️⃣ 参数解密 / 加密拦截器 🕵️‍♂️

目的:对敏感参数进行解密处理,避免暴露明文。

public class DecryptInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)throws Exception {String encrypted = request.getParameter("data");if (encrypted != null) {String decrypted = AESUtil.decrypt(encrypted);request.setAttribute("decryptedData", decrypted);}return true;}
}

📌 更严谨的做法是配合 HttpServletRequestWrapper 改写参数,或使用 AOP 切面做解密处理。


✅ 总结

拦截器名称应用场景核心方法
登录鉴权登录校验、权限控制preHandle()
接口限流防止刷接口、重复请求preHandle()
日志跟踪日志链路追踪preHandle()afterCompletion()
参数加解密保护敏感数据传输preHandle()

你可以组合使用多个拦截器构建完整的“请求防火墙”,让系统更安全、更健壮、更易维护 🚀


六、注意事项与最佳实践 📌

拦截器虽然好用,但也不是“万能胶水”,用不好不仅效率低,还容易埋下“隐形炸弹”。下面是开发中总结出的几个关键建议,助你避坑+提效 ✅


1️⃣ 避免拦截器滥用 🚫

拦截器适合处理横切关注点,不宜塞入业务逻辑!

  • ❌ 不要在拦截器中调用数据库或远程接口做复杂业务判断;

  • ❌ 不要在拦截器中写 if-else 处理业务流程分支;

  • ✅ 应该专注做认证、日志、限流、数据预处理等通用任务。

📌 把拦截器当作“守门员”而不是“中场指挥官”


2️⃣ 拦截器中不要执行耗时操作 🐢

拦截器运行在请求链最前面,一旦卡住,就等于所有请求都被堵住了

  • ❌ 不建议做复杂计算、大数据遍历、延时操作;

  • ✅ 把耗时任务丢到 MQ、线程池或异步逻辑中处理;

  • ✅ 如必须处理,建议加缓存或设定超时时间 ⏱️。


3️⃣ 异常处理与容错设计 🧯

如果拦截器抛出异常,整个请求就直接挂了……

建议处理方式:

  • ✅ 用 try-catch 包裹敏感逻辑,避免错误传递到 Controller;

  • ✅ 配合 afterCompletion() 做清理工作;

  • ✅ 出错时设置 HTTP 状态码或返回友好提示信息;

try {// some logic
} catch (Exception e) {response.setStatus(500);response.getWriter().write("系统内部错误,请稍后再试");return false;
}

4️⃣ 拦截器的可测试性与可维护性 🧪

别让拦截器变成“不可单测的黑盒”:

  • ✅ 尽量将逻辑抽出为独立的工具类或 Service,便于测试;

  • ✅ 避免直接在拦截器中写大量逻辑判断;

  • ✅ 为拦截器添加日志或 Trace ID,方便排查问题;

示例

if (!authService.checkPermission(user, request.getRequestURI())) {log.warn("无权限访问: {}", request.getRequestURI());response.sendRedirect("/403");return false;
}

✅ 总结一句话:

拦截器越轻巧越好,越专注越安全,越解耦越持久。


七、总结 🧭

走到这里,我们已经把 Java 拦截器的前世今生都聊透了。从基本原理,到实战场景,再到注意事项和最佳实践,最后我们来为这篇文章画个圆满的句号 ✅


✅ 拦截器的优势与不足 ⚖️

优势 💪不足 ⚠️
统一处理横切关注点(如登录、日志)粒度有限,基于请求级别
实现简单,集成方便(尤其在 Spring MVC 中)不适合复杂业务逻辑
不依赖注解或代理,适合非 Spring 控制层拓展性、灵活性略低于 AOP
可以实现路径级别的精细控制不适用于方法内部逻辑处理

🤔 何时用拦截器,何时用 AOP?

拦截器 vs AOP,不是“谁好谁坏”,而是“谁更适合”:

使用场景推荐方案
登录校验、权限控制、日志追踪、请求预处理✅ 拦截器
方法级别的日志、事务、缓存、异常处理✅ AOP(@Aspect)
非 Spring 项目或与 Servlet 相关的过滤逻辑✅ Filter
对所有请求进行统一拦截拦截器 or Filter

🎯 简单记:

“面向请求” → 拦截器,
“面向方法” → AOP,
“低层控制” → Filter。


🧱 拦截器能让系统更“可插拔”吗?

答案是 ✅ 可以

  • 将公共逻辑提取成拦截器,使控制器保持“干净”;

  • 所有新增功能(限流、审计、追踪)都可以通过新建拦截器实现,无需侵入原有业务代码;

  • 拦截器组合 + 精准路径配置,构建“模块化的请求处理流程”;

这是一种“像拼乐高一样搭系统”的思路,非常适合构建高扩展性、高可维护性的后端架构 🧩


📌 最后的最后,一句话送给你:

“让拦截器做它擅长的事,让系统更清晰、更健壮。”


好的!来一份精炼到位、适合打印/收藏/贴墙的 ✅Java 拦截器速查表(Cheat Sheet),帮你查阅不迷路,一页吃透精华内容 🚀💡

🧾附录:Java 拦截器速查表 Cheat Sheet


✅ 拦截器三大主角

类型场景特点
Filter(Servlet)请求预处理、资源过滤最底层,独立于 Spring,可拦截所有请求
HandlerInterceptor(Spring MVC)登录校验、日志、限流控制器执行前后切入,路径可控,最常用
AOP(@Aspect)方法级别日志、事务、缓存基于注解/切面,粒度更细,适合业务逻辑处理

🚦 拦截器核心方法(Spring)

方法名作用描述执行时机
preHandle()请求前处理,返回 false 拦截请求Controller 前
postHandle()请求处理后,但尚未渲染视图Controller 后
afterCompletion()请求完全结束,用于资源清理渲染视图后(无论成功/失败)

💡 常见用途实战场景

用途描述推荐方案
登录拦截未登录用户重定向至登录页拦截器 + Session
权限控制判断用户权限是否足够拦截器 + 注解/AOP
接口限流控制访问频率,防刷防爆拦截器 + Redis
日志追踪给每个请求生成 traceId拦截器 + MDC 日志
参数解密请求参数加密传输,后端解密拦截器 + Wrapper

⚙️ 控制顺序 & 注册技巧

  • 执行顺序preHandle() 正序 → postHandle() & afterCompletion() 逆序

  • 注册顺序:决定执行顺序(优先注册优先执行)

  • @Order 注解:Bean 注入方式时可设置优先级(数值越小越先执行)


🚫 拦截器开发注意事项

建议原因
✅ 保持职责单一避免逻辑混乱,易维护
❌ 避免耗时操作拦截器在请求入口,影响整体性能
✅ 处理异常 & 清理资源保证服务健壮性 & 防止内存泄露
✅ 可测试性好将逻辑抽出为 Service,方便单元测试
✅ 拦截路径精准配置(include/exclude)防止不必要的拦截,提高效率

🎯 拦截器 vs AOP 使用建议

使用场景推荐方式
请求路径级别、认证限流等拦截器
业务方法级别、事务/日志等AOP(@Aspect)
静态资源过滤、低层处理Filter

🧩 一图胜千言(推荐搭配架构图使用)

Filter → Interceptor → Controller → AOP → Service
✅ 从粗到细,层层递进,职责明确!


🔚 结语

拦截器虽小,却是构建高质量 Java Web 应用不可或缺的一环。它不仅能提升系统的安全性可维护性,更为我们提供了模块化扩展的灵活能力。

希望这篇文章能帮你全面理解拦截器的设计理念与实践方式,从 Filter 到 Spring Interceptor,再到 AOP 的结合应用,搭建出一套稳健、可控、可持续演进的后端架构。

技术是工具,架构是思维,落地才是王道。

如果你觉得这篇文章对你有帮助,欢迎 👍 点赞收藏,或转发给有需要的同事朋友。后续我也会继续分享更多 Java & Spring 实战干货,咱们下篇见!👋😄

相关文章:

Java 拦截器完全指南:原理、实战与最佳实践

一、引言 拦截器的基本概念 在现代 Java Web 开发中&#xff0c;拦截器&#xff08;Interceptor&#xff09;是一种用于在请求处理前后插入自定义逻辑的机制。简单来说&#xff0c;它是一种“横切逻辑处理器”&#xff0c;可以用来对请求进行预处理、后处理&#xff0c;甚至终…...

2025.04.23华为机考第二题-200分

📌 点击直达笔试专栏 👉《大厂笔试突围》 💻 春秋招笔试突围在线OJ 👉 笔试突围OJ 02. 魔法彩灯森林 问题描述 在卢小姐的魔法花园中,有一棵神奇的彩灯树。这棵树的每个节点都装有一盏魔法灯,灯有三种颜色状态:红色(用数字1表示)、绿色(用数字2表示)和蓝色(…...

【Leetcode 每日一题】1399. 统计最大组的数目

问题背景 给你一个整数 n n n。请你先求出从 1 1 1 到 n n n 的每个整数 10 10 10 进制表示下的数位和&#xff08;每一位上的数字相加&#xff09;&#xff0c;然后把数位和相等的数字放到同一个组中。 请你统计每个组中的数字数目&#xff0c;并返回数字数目并列最多的组…...

系统重装——联想sharkbay主板电脑

上周给一台老电脑重装系统系统&#xff0c;型号是lenovo sharkbay主板的电脑&#xff0c;趁着最近固态便宜&#xff0c;入手了两块长城的固态&#xff0c;装上以后插上启动U盘&#xff0c;死活进不去boot系统。提示 bootmgr 缺失&#xff0c;上网查了许久&#xff0c;终于解决了…...

Python数据清洗笔记(上)

一、数据清洗概述 数据清洗是数据分析过程中至关重要的一步&#xff0c;约占整个数据分析过程的60%-80%的时间。主要包括处理缺失值、异常值、重复值、格式不一致等问题。 二、常用工具 主要使用Python的Pandas库进行数据清洗&#xff1a; import pandas as pd import nump…...

三、Python编程基础03

目录 一、debug 调试的使用1. 打断点2. 右键 Debug 运行代码3. 单步执行代码,查看过程 二、字符串1、定义与下标引用2、切片3、查找4、去除空白字符5、转换大小写与拆分6、其他方法-替换、连接、是否为纯数字7、登录案例优化 三、列表 list1、列表基础操作2、案例&#xff1a; …...

西门子S7-200SMART 控制Profinet闭环步进MD-4250-PN (1)电机及专栏介绍

一、前言 本系列是我继 《西门子S7-1200PLC 控制步进电机 MD-4240-PN》系列专栏后&#xff0c;新开的一篇专栏。 系列的主题围绕 S7-200SMART Profinet闭环步进(MD-4250-PN) 触摸屏的硬件&#xff0c;预计作四篇文章&#xff0c;分别为&#xff1a;专栏介绍、硬件介绍、PLC…...

NoSQL 简单讲解

目录 1. NoSQL 的背景与意义 1.1 数据库的演变 1.2 NoSQL 的兴起 2. NoSQL 数据库的分类 2.1 键值存储&#xff08;Key-Value Stores&#xff09; 2.2 文档数据库&#xff08;Document Stores&#xff09; 2.3 列族存储&#xff08;Column-Family Stores&#xff09; 2.…...

TCP 协议:原理、机制与应用

一、引言 在当今数字化的时代&#xff0c;网络通信无处不在&#xff0c;而 TCP&#xff08;Transmission Control Protocol&#xff0c;传输控制协议&#xff09;作为互联网协议栈中的核心协议之一&#xff0c;扮演着至关重要的角色。无论是浏览网页、发送电子邮件还是进行文件…...

C++23 新特性:令声明顺序决定非静态类数据成员的布局 (P1847R4)

文章目录 引言背景知识非静态类数据成员类的内存布局 P1847R4提案内容示例代码 影响和优势提高代码的可预测性与其他语言和库的交互更加方便简化代码调试和优化 编译器支持情况实际应用场景嵌入式系统开发跨语言编程内存优化 总结 引言 在C的发展历程中&#xff0c;每一个新版…...

Java 环境配置详解(Windows、macOS、Linux)

Java 环境配置是学习和开发 Java 程序的第一步&#xff0c;也是至关重要的一步。一个正确配置的 Java 环境能够保证你的 Java 程序能够顺利编译、运行和调试。本文将详细介绍在 Windows、macOS 和 Linux 三种主流操作系统上配置 Java 环境的步骤&#xff0c;力求详尽、易懂&…...

ChatBEV:一种理解 BEV 地图的可视化语言模型

25年3月来自上海交大、上海AI实验室、同济大学和MAGIC的论文“ChatBEV: A Visual Language Model that Understands BEV Maps”。 交通场景理解对于智能交通系统和自动驾驶至关重要&#xff0c;可确保车辆安全高效地运行。虽然 VLM 的最新进展已显示出整体场景理解的前景&…...

利用Python爬虫实现百度图片搜索的PNG图片下载

在图像识别、训练数据集构建等场景中&#xff0c;我们经常需要从互联网上批量下载图片素材。百度图片是中文搜索中最常用的来源之一。本文将介绍如何使用Python构建一个稳定、可扩展的百度图片爬虫&#xff0c;专门用于下载并保存高清PNG格式图片。 一、项目目标 本项目的目标…...

自主可控鸿道Intewell工业实时操作系统

鸿道Intewell工业实时操作系统是东土科技旗下科东软件自主研发的新一代智能工业操作系统&#xff0c;以下是相关介绍&#xff1a; 系统架构 -Intewell-C全实时构型&#xff1a;设备上只运行自研RTOS的全实时系统&#xff0c;适用于有功能安全认证需求的实时控制场景&#xf…...

【数据结构入门训练DAY-21】信息学奥赛一本通T1334-围圈报数

文章目录 前言一、题目二、解题思路结语 前言 本次训练内容 STL库中队列的使用练习。训练解题思维 一、题目 有&#xff4e;个人依次围成一圈&#xff0c;从第&#xff11;个人开始报数&#xff0c;数到第&#xff4d;个人出列&#xff0c;然后从出列的下一个人开始报数&am…...

【C语言】C语言中的字符函数和字符串函数全解析

前言 在C语言编程中&#xff0c;字符和字符串的处理是必不可少的。C语言标准库提供了丰富的字符和字符串函数&#xff0c;这些函数极大地简化了字符和字符串的操作。本文将详细介绍这些函数的使用方法、模拟实现以及一些实用的代码示例&#xff0c;帮助你更好地理解和掌握它们…...

声纹振动传感器在电力监测领域的应用

声纹振动传感器在电力监测领域有多种应用&#xff0c;主要包括以下几个方面&#xff1a; 变压器监测 故障诊断&#xff1a;变压器在运行过程中会产生特定的声纹和振动信号&#xff0c;当变压器内部出现故障&#xff0c;如绕组短路、铁芯松动、局部放电等&#xff0c;其声纹和振…...

配色之道:解码产品设计中的UI设计配色艺术

在数字化时代&#xff0c;用户界面&#xff08;UI&#xff09;作为产品与用户交互的桥梁&#xff0c;其设计质量直接影响着用户体验与产品成败。而配色&#xff0c;作为UI设计中最为直观且富有表现力的元素之一&#xff0c;不仅是视觉美学的体现&#xff0c;更是情感传递、信息…...

python基础语法测试

1. 关于Python语言数值操作符&#xff0c;以下选项中描述错误的是 A x%y表示x与y之商的余数&#xff0c;也称为模运算 B x/y表示x与y之商 C x**y表示x的y次幂&#xff0c;其中&#xff0c;y必须是整数 D x//y表示x与y之整数商&#xff0c;即不大于x与y之商的最大整数2. 下面代码…...

如何安装Visio(win10)

首先下载下面这些文件 HomeStudent2021Retail.img officedeploymenttool_17531-20046.exe office中文语言包.exe 确保这些文件都在一个文件夹内&#xff08;我已经上传这些资源&#xff0c;这些资源都是官网下载的&#xff09; 官网资源下载教程 1.下载Office镜像&#xff0…...

Sql刷题日志(day5)

面试&#xff1a; 1、从数据分析角度&#xff0c;推荐模块怎么用指标衡量&#xff1f; 推荐模块主要目的是将用户进行转化&#xff0c;所以其主指标是推荐的转化率推荐模块的指标一般都通过埋点去收集用户的行为并完成相应的计算而形成相应的指标数据&#xff0c;而这里的驱动…...

.NET、java、python语言连接SAP系统的方法

💡 本文会带给你 可用哪些技术与Sap系统连接怎样用Rfc技术连接SAP一. SAP系统与外部系统集成技术 SAP系统提供了多种方式供Java、.NET、Python等外部编程语言进行连接和集成。 1. RFC (Remote Function Call) 连接 适用语言:Java, .NET, Python, 其他支持RFC的编程语言 …...

C++ 容器查找效率

C 容器查找效率 只要选对容器&#xff0c;多写几行代码就能让程序“飞”起来。下面用生活化的比喻 足够多的带注释示例&#xff0c;帮你弄懂常用 STL 容器的查找特性。 读完你应该能快速判断&#xff1a;“我的场景该用哪一个&#xff1f;” 0. 先把“查找复杂度”聊明白 记号…...

汽车可变转向比系统的全面认识

一、什么是转向比&#xff1f; 转向比又叫转向传动比&#xff0c;是指方向盘转向角度与车轮转向角度之比。 例如&#xff0c;方向盘向左转动了60角&#xff0c;而车轮则向左转动了30角&#xff0c;转向比就是2&#xff1a;1。 转向比越大&#xff0c;意味着要使车轮转向达到指…...

知识储备-后仿

仿真环境设定 mem、constant input(scan/test)等设非x初值无复位ff通过force-release处理vcs timing_check、optconfigfile (自定义配置&#xff0c;如指定模块timing check与否&#xff09;设置运行核数、仿真精度不要过小设置、根据测试目的选择性关闭、dump范围(时间/空间)…...

C# AutoResetEvent 详解

一、简介 AutoResetEvent 是 .NET 中一个重要的线程同步原语&#xff0c;用于线程间的信号通知。下面我将从多个方面详细讲解 AutoResetEvent。 AutoResetEvent 是 System.Threading 命名空间下的一个类&#xff0c;它表示一个线程同步事件&#xff0c;在等待线程被释放后会自…...

【水印图片文字识别】水印相机拍摄的照片提取重要的信息可以批量改名,批量识别水印文字内容批量给图片改名,基于QT和腾讯OCR的识别方案

应用场景 在日常工作和生活中,人们使用水印相机拍摄的照片往往包含重要的信息,如拍摄地点、时间、事件等。这些信息以水印的形式存在于照片中。当需要对大量照片进行管理时,手动为每张照片重命名是一项繁琐且容易出错的工作。通过批量识别水印文字内容并为图片改名,可以提…...

【架构】Armstrong公理系统通俗详解:数据库设计的基本法则

关系数据库就像一本精心设计的通讯录&#xff0c;而Armstrong公理系统则是帮我们整理这本通讯录的基本规则。本文将用简单易懂的语言和生活实例&#xff0c;带你理解这套看似复杂的理论。 1. 什么是函数依赖&#xff1f; 想象你有一个学生信息表&#xff0c;包含学号、姓名、…...

Redis高频核心面试题

1.阐述Redis的主要的特性和优势 &#xff1f; 【Redis 的主要特性】 &#xff08;1&#xff09;Redis 是完全开源免费的&#xff0c;遵守 BSD 协议&#xff0c;是一个高性能的 key-value 数据库 &#xff08;2&#xff09;Redis 与其他 key - value 缓存产品有以下三个特点&a…...

Vue3-原始值的响应式方案ref

一、原始类型的值 原始类型的指的是: boolean、number、string、symbol、undefind和null等类型的值. 一、初识ref 为什么vue3需要对原始值的响应式做单独处理?因为Javascript中的Proxy只能代理对象类型的数据, 如普通对象、数组、Set、Map等。 为了解决Proxy不能代理原始类…...

VUE的创建

Vue Vue的创建脚手架创建Vue的解析setup函数:插值表达式数据响应式 ⽬录和⽂件解读指令 Vue的创建 下载VScode https://code.visualstudio.com/download 加入拓展包 点击 然后输入代码 <!DOCTYPE html> <html lang"en"><head><meta charset&…...

第51讲:AI在农业政策支持系统中的应用——用人工智能点亮科学决策的新范式

目录 🧠 开篇引导:农业决策,如何更科学? 🤖 什么是“AI驱动的农业政策支持系统”? 🧪 案例解析:AI如何助力农业政策? 🌾 案例一:政策补贴的智能匹配 🌍 案例二:土地利用规划支持 🛠 AI在农业政策建模中的常用技术 📈 可视化与接口建议 🌟 未来…...

开关电源LM5160-Q1 在 Fly-Buck 电路中的硬件设计与 PCB Layout 优化

一、LM5160-Q1 规格书深度解读与硬件设计参数提取 核心功能 宽输入范围:4.5V~65V,支持汽车级输入电压波动(AEC-Q100 标准,温度等级 1:-40C~125C)。 集成度:内置高侧 / 低侧 MOSFET,无需外部肖特基二极管,同步降压 / Fly-Buck 双模式。 控制架构:自适应恒定导通时间…...

面向 C# 初学者的完整教程

&#x1f9f1; 一、项目结构说明 你的项目大致结构如下&#xff1a; TaskManager/ ├── backend/ │ ├── TaskManager.Core/ // 实体类和接口 │ ├── TaskManager.Infrastructure/ // 数据库、服务实现 │ └── TaskManager.API/ // We…...

Python实现孔填充与坐标转换

一、问题背景 在工业自动化、材料加工等领域&#xff0c;常需要在图像识别的闭合区域内生成等间距的孔位坐标。本文基于OpenCV库&#xff0c;提出一种从图像边界提取到物理坐标生成的完整解决方案&#xff0c;实现以下核心功能&#xff1a; 像素坐标到实际尺寸的转换安全间距…...

精益数据分析(16/126):掌握关键方法,探寻创业真谛

精益数据分析&#xff08;16/126&#xff09;&#xff1a;掌握关键方法&#xff0c;探寻创业真谛 大家好&#xff01;在创业与数据分析的学习道路上&#xff0c;每一次的探索都让我们离成功更近一步。今天&#xff0c;我带着和大家共同进步的初心&#xff0c;继续深入解读《精…...

pytorch(gpu版本安装)

Pytorch官网下载很慢 选择以下方法&#xff0c;关于版本对应从pytorch官网查看 官网方法 pip install torch2.2.0 torchvision0.17.0 torchaudio2.2.0 --index-url https://download.pytorch.org/whl/cu121 其他方法 pip install torch2.2.0cu121 torchvision0.17.0cu121 t…...

day001

文章目录 1. 常用Linux发行版本2. 常用的Linux系统及版本3. Linux系统运行在哪&#xff1f;4. 安装kylin虚拟机4.1 环境准备4.2 新建虚拟机4.3 配置虚拟机参数4.4 同意系统使用协议4.5 登录系统&#xff0c;查看ip4.6 保存系统快照 5. 远程连接5.1 连接类型对比5.2 使用Xshell连…...

k8s 证书相关问题

1.重新生成新证书 kubeadm init phase certs apiserver-etcd-client --config ~/kubeadm.yaml这个命令表示生成 kube-apiserver 连接 etcd 使用的证书,生成后如下 -rw------- 1 root root 1.7K Apr 23 16:35 apiserver-etcd-client.key -rw-r--r-- 1 root root 1.2K Apr 23 …...

Spring JDBC 的开发步骤(注解方式)

Spring JDBC 的开发步骤主要包括以下关键环节&#xff0c;结合代码示例说明如下&#xff1a; 1. 添加依赖 在 pom.xml 中引入 Spring JDBC 和数据库驱动依赖&#xff08;以 HikariCP 连接池和 MySQL 为例&#xff09;&#xff1a; <!-- Spring JDBC --> <dependency…...

蓝桥杯 15.小数第n位

小数第n位 原题目链接 题目描述 我们知道&#xff0c;整数做除法时&#xff0c;有时会得到有限小数&#xff0c;有时会得到无限循环小数。 如果我们把有限小数的末尾加上无限多个 0&#xff0c;它们就具有了统一的形式。 本题的任务是&#xff1a;在上述约定下&#xff0c…...

[计算机科学#1]:计算机的前世今生,从算盘到IBM的演变之路

【核知坊】&#xff1a;释放青春想象&#xff0c;码动全新视野。 我们希望使用精简的信息传达知识的骨架&#xff0c;启发创造者开启创造之路&#xff01;&#xff01;&#xff01; 内容摘要&#xff1a;在我们的日常生活中&#xff0c;计算机无处不在——…...

【LangChain4j】AI 第一弹:LangChain4j 的理解

一、LangChain4j 的简介 1.1 LangChain4j的背景 LangChain4j&#xff08;LangChain for java&#xff09; 的目标是简化将大语言模型&#xff08;LLM - Large Language Model&#xff09;集成到 Java 应用程序中的过程。 官网&#xff1a; https://docs.langchain4j.dev 202…...

深入解析C++ STL Stack:后进先出的数据结构

一、引言 在计算机科学中&#xff0c;栈&#xff08;Stack&#xff09;作为一种遵循后进先出&#xff08;LIFO&#xff09;​原则的数据结构&#xff0c;是算法设计和程序开发的基础构件。C STL中的stack容器适配器以简洁的接口封装了底层容器的操作&#xff0c;为开发者提供了…...

3.2 Agent核心能力:感知、规划、决策与执行

智能代理&#xff08;Agent&#xff09;是一种能够在复杂环境中自主运作的计算实体&#xff0c;其智能行为依赖于四大核心能力&#xff1a;感知&#xff08;Perception&#xff09;、规划&#xff08;Planning&#xff09;、决策&#xff08;Decision-making&#xff09;和执行…...

(即插即用模块-特征处理部分) 四十一、(2024) MSAA 多尺度注意力聚合模块

文章目录 1、Multi-Scale Attention Aggregation Module2、代码实现 paper&#xff1a;CM-UNet: Hybrid CNN-Mamba UNet for Remote Sensing Image Semantic Segmentation Code&#xff1a;https://github.com/XiaoBuL/CM-UNet 1、Multi-Scale Attention Aggregation Module 传…...

【速写】hook与fx

文章目录 问题方法方法 1&#xff1a;使用 PyTorch 的 register_forward_hook方法 2&#xff1a;自定义前向传播&#xff08;修改 forward 方法&#xff09;方法 3&#xff1a;使用 output_attentions 或 output_hidden_states方法 4&#xff1a;使用 torch.fx 进行动态追踪总结…...

基于javaweb的SpringBoot扶农助农平台管理系统设计与实现(源码+文档+部署讲解)

技术范围&#xff1a;SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、小程序、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容&#xff1a;免费功能设计、开题报告、任务书、中期检查PPT、系统功能实现、代码编写、论文编写和辅导、论文…...

用户模块-SpringEvent观察者模式

1. 背景与需求 在很多系统中&#xff0c;我们常常需要对用户的行为进行处理&#xff0c;比如发放奖励、处理通知等。在这个例子中&#xff0c;我们希望在两个场景下发放“改名卡”这个奖励&#xff1a; 用户注册时&#xff1a;当一个新用户注册成功时&#xff0c;我们希望立即发…...

三目云台转动性能稳定性

三目云台是一种具备三个摄像头或观测窗口的云台设备&#xff0c;其转动性能对于实现全方位、多角度的监控或观测至关重要。以下是对三目云台转动的详细分析&#xff1a; 一、转动原理 云台本身是一种摄像机稳定器&#xff0c;通过内置的电机和控制系统实现转动。三目云台则在…...