15、(行为型设计模式)Java 责任链模式深度学习指南

责任链模式(Chain of Responsibility Pattern)—— 嵌套拦截器 一、what is 责任链模式? 我前面的文章介绍过动态代理模式,该模式设计者只需要向开发者暴露拦截器即可。当有多个拦截器时,就衍生出了责任链。 什么是责任链?比如请假流程:请假单看成对象,你要请假需要经过开发经理、部门经理、人事部门负责人等多个环节,每个环节的人都可以拦截你的请假申请单进行修改或审批,这里把每个环节都看成拦截器的话,总共有三个拦截器。 一个对象在一条链上被多个拦截器处... 阅读详情

以下是为你精心撰写的 《Java 责任链模式深度学习指南》,专为 Java 后端开发者打造,内容涵盖:定义、作用、与过滤器/拦截器的深度对比、真实业务场景、手写实现、Spring Filter/AOP 实现、Spring Gateway 实现、避坑指南、最佳实践、面试高频题,所有示例均含中文注释,可直接用于项目重构、权限校验、风控拦截、日志记录、API 网关、审批流等核心场景。


📘 Java 责任链模式深度学习指南

—— 从“多重 if-else”到“流水线式拦截”的架构升级

作者:Java 后端架构实战导师
适用对象:Java 后端开发者(Spring Boot / 微服务 / API 网关 / 风控系统 / 权限系统)
目标:彻底掌握“让多个对象有机会处理请求,形成一条处理链”的核心模式,告别“嵌套 if-else”和“硬编码顺序”
核心原则:“我不是唯一处理者,我只是链上的一环,传下去,或拦住它。”


✅ 一、什么是责任链模式?

📌 定义:

责任链模式(Chain of Responsibility Pattern) 是一种行为型设计模式,它将请求的发送者和接收者解耦,使多个对象都有机会处理这个请求。请求沿着一条处理链传递,直到有一个对象处理它为止。

🔍 核心思想:

  • 一组处理器(Handler) 组成一条链
  • 每个处理器只关心自己是否能处理,不能处理就传递给下一个
  • 请求从链头开始,逐级传递,直到被处理或链尾
  • 每个处理器可选择:
    • ✅ 自己处理并终止链
    • ✅ 自己处理并继续传递
    • ✅ 不处理,直接传递给下一个
  • 客户端不知道由谁处理,只负责发起请求

💡 一句话记忆:
“我要找领导签字,先找组长,他没权限就找主管,主管没权限就找总监——谁有权限谁处理,不关我的事。”

🆚 责任链模式 vs 多重 if-else

方式多重 if-else责任链模式
结构所有逻辑写在一个地方每个条件独立成一个类
扩展性新增规则需修改原代码新增处理器只需注册到链中
可读性嵌套深,难维护结构清晰,职责单一
顺序控制固定写死可动态调整顺序
复用性代码复用差处理器可复用在多个链中
典型场景小型工具类权限、风控、日志、过滤器

✅ 经典比喻:
你去银行办业务:

  • if-else:柜员问你“是转账?是开户?是挂失?” → 一连串 if 判断
  • 责任链:你先找大堂经理 → 他判断“是咨询” → 转给客户经理 → 他判断“是开户” → 转给柜台 → 柜台处理 → 完成

✅ 二、责任链模式有什么作用?(Why Use Chain of Responsibility?)

作用说明
✅ 消除嵌套 if-else避免“if (A) { if (B) { if © { … } } }”的地狱结构
✅ 支持动态扩展新增拦截器/过滤器只需新增类,不改原有代码
✅ 支持灵活顺序可配置处理器执行顺序,如:日志 → 权限 → 限流 → 业务
✅ 解耦请求者与处理者客户端无需知道谁处理、怎么处理
✅ 支持条件终止一个处理器处理完可终止链,避免后续无效处理
✅ 支持组合处理多个处理器可协同完成复杂逻辑(如:鉴权 + 审计 + 缓存)
✅ 提高可测试性每个处理器可独立单元测试
✅ 支撑拦截器架构Spring Filter、Spring Interceptor、Netty ChannelHandler 都是责任链模式

💡 经典名言:
“Avoid coupling the sender of a request to its receiver by giving more than one object a chance to handle the request.”
——《Design Patterns: Elements of Reusable Object-Oriented Software》


✅ 三、责任链模式的典型使用场景(Java 后端真实案例)

场景说明是否推荐使用责任链模式
✅ API 网关拦截器日志 → 鉴权 → 限流 → 签名验证 → 路由✅ 强烈推荐
✅ Web 请求过滤器Encoding → CORS → XSS 防护 → Session 检查✅ 强烈推荐
✅ 订单风控系统黑名单 → 频率限制 → IP 地域 → 设备指纹 → 人工审核✅ 强烈推荐
✅ 审批流程提交 → 部门主管 → 财务 → 总监 → 归档✅ 强烈推荐
✅ 日志记录记录请求参数 → 记录响应时间 → 记录用户 → 记录IP✅ 推荐
✅ 消息队列消费者消息解码 → 校验格式 → 业务处理 → 重试 → 死信队列✅ 推荐
✅ Spring Security认证 → 授权 → 会话管理 → CSRF 防护✅ 推荐
✅ 缓存预热检查本地缓存 → 检查 Redis → 查询 DB → 写入缓存✅ 推荐
✅ 数据校验非空校验 → 格式校验 → 业务规则校验 → 数据库唯一性校验✅ 推荐
❌ 单一校验只有“用户名非空”一个判断❌ 直接写 if 即可
❌ 顺序固定、不可变所有请求都必须走 5 个步骤,无选择❌ 用模板方法更清晰
❌ 必须全部执行每个环节都必须执行,无终止❌ 用装饰器或策略模式

✅ 判断标准:
“有一系列处理步骤,它们有先后顺序,但不是每个都必须执行,且可能中途终止?”
→ 是 → 用责任链模式!


✅ 四、责任链模式的三种实现方式详解(含中文注释)

我们从手写经典版到Spring Filter/AOP,再到Spring Gateway,逐步深入。


🔹 1. 手写责任链模式(经典实现)

/**
 * 【1】处理器接口:定义处理方法和下一个处理器
 */
interface RequestHandler {
    boolean handle(Request request); // 返回 true 表示已处理,终止链;false 表示继续传递
    void setNext(RequestHandler next); // 设置下一个处理器
}

/**
 * 【2】基础处理器抽象类(可选,简化代码)
 */
abstract class AbstractRequestHandler implements RequestHandler {
    protected RequestHandler next;

    @Override
    public void setNext(RequestHandler next) {
        this.next = next;
    }

    /**
     * 模板方法:统一处理逻辑
     */
    @Override
    public boolean handle(Request request) {
        boolean handled = doHandle(request);
        if (!handled && next != null) {
            return next.handle(request); // 继续传递
        }
        return handled; // 已处理或链尾
    }

    /**
     * 子类必须实现的具体处理逻辑
     */
    protected abstract boolean doHandle(Request request);
}

/**
 * 【3】具体处理器1:日志记录
 */
class LoggingHandler extends AbstractRequestHandler {
    @Override
    protected boolean doHandle(Request request) {
        System.out.println("📝 日志:接收到请求,路径:" + request.getPath() + ",参数:" + request.getParams());
        // 日志不终止链,继续传递
        return false;
    }
}

/**
 * 【4】具体处理器2:黑名单拦截
 */
class BlacklistHandler extends AbstractRequestHandler {
    @Override
    protected boolean doHandle(Request request) {
        String ip = request.getIp();
        if ("192.168.1.100".equals(ip)) {
            System.out.println("⛔ 黑名单拦截:IP " + ip + " 被禁止访问");
            return true; // ✅ 终止链,不再传递
        }
        System.out.println("✅ 黑名单检查:IP " + ip + " 通过");
        return false; // 继续传递
    }
}

/**
 * 【5】具体处理器3:权限校验
 */
class AuthHandler extends AbstractRequestHandler {
    @Override
    protected boolean doHandle(Request request) {
        String token = request.getToken();
        if (token == null || !token.startsWith("Bearer ")) {
            System.out.println("🚫 权限不足:未提供有效 Token");
            return true; // ✅ 终止链
        }
        System.out.println("✅ 权限校验:Token 验证通过");
        return false; // 继续传递
    }
}

/**
 * 【6】具体处理器4:限流检查
 */
class RateLimitHandler extends AbstractRequestHandler {
    private int limit = 5; // 每分钟最多5次请求(简化实现)
    private int count = 0;

    @Override
    protected boolean doHandle(Request request) {
        count++;
        if (count > limit) {
            System.out.println("⚡ 限流拦截:请求频率过高,已超过每分钟 " + limit + " 次");
            return true; // ✅ 终止链
        }
        System.out.println("✅ 限流检查:当前请求次数:" + count);
        return false; // 继续传递
    }
}

/**
 * 【7】请求对象(上下文)
 */
class Request {
    private String path;
    private String ip;
    private String token;
    private String params;

    public Request(String path, String ip, String token, String params) {
        this.path = path;
        this.ip = ip;
        this.token = token;
        this.params = params;
    }

    // getter 方法
    public String getPath() { return path; }
    public String getIp() { return ip; }
    public String getToken() { return token; }
    public String getParams() { return params; }
}

/**
 * 【8】客户端:构建责任链并触发
 */
public class ChainOfResponsibilityDemo {
    public static void main(String[] args) {
        // ✅ 构建责任链:顺序很重要!
        RequestHandler logging = new LoggingHandler();
        RequestHandler blacklist = new BlacklistHandler();
        RequestHandler auth = new AuthHandler();
        RequestHandler rateLimit = new RateLimitHandler();

        // ✅ 设置链路:日志 → 黑名单 → 权限 → 限流
        logging.setNext(blacklist);
        blacklist.setNext(auth);
        auth.setNext(rateLimit);

        // ✅ 模拟请求1:正常请求
        System.out.println("=== 请求1:合法请求 ===");
        Request request1 = new Request("/api/user", "192.168.1.101", "Bearer abc123", "{}");
        logging.handle(request1); // 从链头开始

        System.out.println("\n=== 请求2:黑名单IP ===");
        Request request2 = new Request("/api/user", "192.168.1.100", "Bearer abc123", "{}");
        logging.handle(request2); // 在黑名单被拦截

        System.out.println("\n=== 请求3:无 Token ===");
        Request request3 = new Request("/api/user", "192.168.1.101", null, "{}");
        logging.handle(request3); // 在权限校验被拦截

        System.out.println("\n=== 请求4:限流触发 ===");
        for (int i = 0; i < 6; i++) {
            Request request = new Request("/api/user", "192.168.1.101", "Bearer abc123", "{}");
            logging.handle(request); // 第6次被限流
        }
    }
}
✅ 输出结果:
=== 请求1:合法请求 ===
📝 日志:接收到请求,路径:/api/user,参数:{}
✅ 黑名单检查:IP 192.168.1.101 通过
✅ 权限校验:Token 验证通过
✅ 限流检查:当前请求次数:1

=== 请求2:黑名单IP ===
📝 日志:接收到请求,路径:/api/user,参数:{}
⛔ 黑名单拦截:IP 192.168.1.100 被禁止访问

=== 请求3:无 Token ===
📝 日志:接收到请求,路径:/api/user,参数:{}
✅ 黑名单检查:IP 192.168.1.101 通过
🚫 权限不足:未提供有效 Token

=== 请求4:限流触发 ===
📝 日志:接收到请求,路径:/api/user,参数:{}
✅ 黑名单检查:IP 192.168.1.101 通过
✅ 权限校验:Token 验证通过
✅ 限流检查:当前请求次数:2
...(省略)
✅ 限流检查:当前请求次数:5
📝 日志:接收到请求,路径:/api/user,参数:{}
✅ 黑名单检查:IP 192.168.1.101 通过
✅ 权限校验:Token 验证通过
⚡ 限流拦截:请求频率过高,已超过每分钟 5 次
✅ 优点:
  • 结构清晰:每个处理器职责单一
  • 可扩展:新增拦截器只需新增类
  • 可配置:链顺序可动态调整
  • 可终止:任意环节可中断请求
  • 符合开闭原则
⚠️ 缺点:
  • 手动维护链顺序,容易出错
  • 没有统一异常处理
  • 不支持异步

🔹 2. 责任链模式 + Spring Filter(Web 层实战)

Spring 的 Filter 就是责任链模式的完美体现!每个 Filter 是一个处理器。

import org.springframework.stereotype.Component;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;

/**
 * 【1】日志过滤器(Filter)
 */
@Component
@WebFilter(urlPatterns = "/*")
public class LoggingFilter implements Filter {

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) request;

        System.out.println("📝 日志:请求路径:" + req.getRequestURI() + ",IP:" + req.getRemoteAddr());

        // ✅ 关键:调用 chain.doFilter() → 传递给下一个 Filter
        chain.doFilter(request, response);

        System.out.println("✅ 日志:请求处理完成");
    }
}

/**
 * 【2】黑名单过滤器
 */
@Component
@WebFilter(urlPatterns = "/*")
public class BlacklistFilter implements Filter {

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) request;
        String ip = req.getRemoteAddr();

        if ("192.168.1.100".equals(ip)) {
            System.out.println("⛔ 黑名单拦截:IP " + ip + " 被禁止访问");
            // ✅ 不调用 chain.doFilter() → 终止链
            return;
        }

        System.out.println("✅ 黑名单检查:IP " + ip + " 通过");
        chain.doFilter(request, response); // 继续传递
    }
}

/**
 * 【3】权限过滤器
 */
@Component
@WebFilter(urlPatterns = "/*")
public class AuthFilter implements Filter {

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) request;
        String token = req.getHeader("Authorization");

        if (token == null || !token.startsWith("Bearer ")) {
            System.out.println("🚫 权限不足:未提供有效 Token");
            return; // ✅ 终止链
        }

        System.out.println("✅ 权限校验:Token 验证通过");
        chain.doFilter(request, response); // 继续传递
    }
}

/**
 * 【4】限流过滤器(简化版)
 */
@Component
@WebFilter(urlPatterns = "/*")
public class RateLimitFilter implements Filter {

    private int count = 0;

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        count++;
        if (count > 5) {
            System.out.println("⚡ 限流拦截:请求频率过高");
            return; // ✅ 终止链
        }

        System.out.println("✅ 限流检查:当前请求次数:" + count);
        chain.doFilter(request, response);
    }
}
✅ Spring Boot 启动类:
@SpringBootApplication
public class FilterChainDemo {
    public static void main(String[] args) {
        SpringApplication.run(FilterChainDemo.class, args);
    }
}
✅ 测试请求:
curl http://localhost:8080/api/user -H "Authorization: Bearer abc123"
✅ 优势:
  • Spring 自动注册:@Component + @WebFilter 自动加入过滤链
  • 顺序可控:通过 @Order 注解指定执行顺序
  • 与 Spring 完全集成:可注入 @Autowired Bean
  • 生产级标准:Spring Security、Spring Cloud Gateway 底层都基于此

✅ 设置顺序:

@Component
@WebFilter(urlPatterns = "/*")
@Order(1) // 第一个执行
public class LoggingFilter implements Filter { ... }

@Component
@WebFilter(urlPatterns = "/*")
@Order(2) // 第二个执行
public class BlacklistFilter implements Filter { ... }

🔹 3. 责任链模式 + Spring Gateway(微服务网关)

Spring Cloud Gateway 是现代微服务网关的标杆,其底层就是责任链模式 + Reactor 响应式实现!

import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.cloud.gateway.filter.OrderedGatewayFilter;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Mono;

@Component
public class LoggingGatewayFilter implements GlobalFilter, Ordered {

    @Override
    public Mono<Void> filter(org.springframework.web.server.ServerWebExchange exchange, GatewayFilterChain chain) {
        System.out.println("📝 日志:请求路径:" + exchange.getRequest().getURI());

        // ✅ 关键:chain.filter(exchange) → 传递给下一个 Filter
        return chain.filter(exchange).then(Mono.fromRunnable(() -> {
            System.out.println("✅ 日志:请求处理完成");
        }));
    }

    @Override
    public int getOrder() {
        return 1; // 执行顺序
    }
}

@Component
public class AuthGatewayFilter implements GlobalFilter, Ordered {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        String token = exchange.getRequest().getHeaders().getFirst("Authorization");

        if (token == null || !token.startsWith("Bearer ")) {
            System.out.println("🚫 权限不足:未提供 Token");
            exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
            return exchange.getResponse().setComplete(); // ✅ 终止链
        }

        System.out.println("✅ 权限校验:Token 验证通过");
        return chain.filter(exchange); // 继续传递
    }

    @Override
    public int getOrder() {
        return 2;
    }
}

@Component
public class RateLimitGatewayFilter implements GlobalFilter, Ordered {

    private static final int LIMIT = 5;
    private static int count = 0;

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        count++;
        if (count > LIMIT) {
            System.out.println("⚡ 限流拦截:请求频率过高");
            exchange.getResponse().setStatusCode(HttpStatus.TOO_MANY_REQUESTS);
            return exchange.getResponse().setComplete(); // ✅ 终止链
        }

        System.out.println("✅ 限流检查:当前请求次数:" + count);
        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
        return 3;
    }
}
✅ application.yml 配置:
spring:
  cloud:
    gateway:
      routes:
        - id: user-service
          uri: http://localhost:8081
          predicates:
            - Path=/api/user/**
✅ 优势:
  • 响应式非阻塞:基于 Reactor,支持高并发
  • 支持复杂路由:可结合 Predicate、Filter、RewritePath
  • 企业级网关标准:Netflix Zuul、Kong、Apigee 都是类似架构
  • 可插拔:自定义 Filter 可热部署

✅ 五、责任链模式 vs 过滤器模式 vs 拦截器模式 对比

模式责任链模式过滤器模式拦截器模式
实现方式手动链式传递Servlet FilterSpring Interceptor
作用域任意 Java 对象Web 层(Servlet 容器)Spring MVC 层
执行时机任意请求进入容器时请求进入 Controller 前
是否支持异步可支持可支持(AsyncContext)可支持(Async)
典型场景风控、审批流日志、安全、编码权限、日志、事务
是否 Spring 管理否否(但可 @Component)✅ 是
推荐度✅ 通用✅ Web 层✅ Spring 项目

✅ 总结:

  • 责任链:通用设计模式
  • Filter:Web 层实现
  • Interceptor:Spring MVC 层实现
    → 三者本质相同,只是作用范围不同

✅ 六、责任链模式的避坑指南(Java 后端高频踩坑)

问题原因解决方案
❌ 没有设置 next链断裂,请求被丢弃✅ 手动调用 setNext(),或用 Spring 自动装配
❌ 顺序错误权限校验在日志前,无法记录✅ 用 @Order 或 List<Handler> 按顺序注入
❌ 忘记调用 chain.doFilter()请求被拦截但无响应✅ 每个处理器必须明确决定是否传递
❌ 异常未处理一个处理器异常,链崩溃✅ 每个 Handler 加 try-catch,或用统一异常处理器
❌ 用责任链做同步业务如“扣库存”必须同步✅ 用事务或同步调用,责任链只做前置校验
❌ 处理器太多导致性能差10+ 个处理器逐级调用✅ 用异步、缓存、批量处理优化
❌ 没有统一终止机制所有处理器都执行✅ 明确设计“是否终止”逻辑

✅ 七、学习建议与进阶路径

阶段建议
📚 第一周将你项目中的“登录校验”多层 if-else 重构为责任链(IP → Token → 权限 → 频率)
📚 第二周用 Spring Filter 实现“请求日志 + 黑名单 + 权限校验”三层过滤
📚 第三周用 Spring Gateway 实现“API 网关”:鉴权 + 限流 + 签名验证
📚 第四周阅读 Spring Security 源码:FilterChainProxy 如何构建责任链?
📚 面试准备准备回答:

“你项目中哪里用了责任链模式?”
“Spring Filter 是责任链模式吗?”
“责任链和模板方法区别?”
“如何保证责任链的顺序?” |


✅ 八、责任链模式面试高频题(附答案)

Q1:责任链模式解决了什么问题?

A:解决了“多个对象都有机会处理请求,且顺序可变、可能中途终止”的问题,避免了嵌套 if-else,实现解耦和扩展。

Q2:Spring Filter 是责任链模式吗?

A:是的!FilterChain 就是责任链,每个 Filter 是一个处理器,chain.doFilter() 就是传递请求。

Q3:责任链模式和模板方法模式的区别?

A:

  • 模板方法:固定流程,子类实现步骤
  • 责任链:动态链,请求逐级传递,可终止
    → 一个是“你必须按我流程走”,一个是“你传给我,我决定接不接”

Q4:如何控制责任链的执行顺序?

A:

  • 手写:调用 setNext() 时按顺序链接
  • Spring:使用 @Order 注解指定优先级
  • Spring Gateway:Ordered 接口定义顺序

Q5:责任链模式适合做事务处理吗?

A:不适合!责任链是前置校验,事务应由模板方法或AOP统一管理,责任链中不应有数据库写入。


✅ 九、总结:责任链模式选型决策树

graph TD
    A[需要多个处理器顺序处理请求吗?] --> B{是否在 Web 层?}
    B -->|是| C{是否是 Spring 项目?}
    C -->|是| D[用 @Component + @WebFilter + @Order]
    C -->|否| E[用 Filter + FilterChain]
    B -->|否| F[用自定义 Handler + setNext() 链式构建]

✅ 最终推荐:

  • Spring Web 项目 → ✅ Filter + @Order(最标准)
  • Spring Cloud Gateway → ✅ GlobalFilter + Ordered(最现代)
  • 非 Web、复杂流程 → ✅ 手写责任链(最灵活)
  • 绝对不要:多重 if-else、顺序硬编码、不终止链

✅ 十、结语:真正的高手,不自己处理,只负责传递

你不是在学“责任链模式”,你是在学“如何让系统各模块各司其职,协同工作”。

✅ 当你看到一个请求经过 5 个过滤器,最终被处理,而你只写了 5 个类,每个类只关心自己那一点逻辑时,你已经掌握了架构设计的艺术。
✅ 当你用 Spring Gateway 实现“全球限流 + 多租户鉴权 + 签名验证”,而前端只发一个请求时,你已经是网关架构师了。

不要为了“用模式”而用模式,
要为了“系统可扩展、可维护、可监控”而选择它。


【信息科学与工程学】计算机科学与自动化 第二百零一十一 软件开发模型01 编号类型模型领域模型中的知识点/因素/参数关联知识和法律法规1传统顺序模型瀑布模型 (Waterfall)通用软件开发、硬件紧密耦合系统、政府/军工项目、需求稳定的传统信息系统严格线性阶段:可行性研究→需求分析(SRS,含功能/非功能/接口/约束,使用IEEE 830模板)→系统设计(概要设计HLD:架构、模块划分、数据库ER图;详细设计LLD:伪代码、类图、接口定义)→实现(编码规范、代码审查、静态分析工具SonarQube)→测试(单元测试JUnit、集成测试、系统测试、验收测试UAT,测试计划提前编写 阅读详情

相关推荐

基于OkHttp3+Retrofit2+RxJava3搭建响应式网络框架

本文介绍了一个基于OkHttp3+Retrofit3+RxJava3的响应式网络框架设计。该框架采用分层架构,OkHttp3负责底层网络请求,Retrofit3封装HTTP接口,RxJava3实现响应式流处理。核心亮点包括:1)高度解耦的分层设计;2)统一的异常处理和响应体封装;3)RxJava3实现线程切换和请求管理;4)MVVM架构适配,业务层只需关注数据逻辑。框架提供了完整的实现方案,包括全局配置、拦截器、响应转换、接口声明、仓库封装等组件,并支持生产环境扩展功能如Cookie持久化、Token刷新等

fuge2008的博客 869

Tomcat服务器学习和使用(二)

一、打包JavaWeb应用   在Java中,使用"jar"命令来对将JavaWeb应用打包成一个War包,jar命令的用法如下:    范例:将JavaWebDemoProject这个JavaWeb应用打包成war包      执行完之后,就可以得到一个文件,平时开发完JavaWeb应用后,一般都会将JavaWeb应用打包成一个war包,然后将这个war包放到Tom

Utopia87的博客 1131

(10)Proteus 8.9上的STM32仿真系列(HAL)---freertos

实验设计:通过cubemxide生成freertos工程,然后创建一个 pc13 led灯间隔200ms闪烁的任务。非常遗憾的是proteus8.9仿真失败,实物上没有问题,但还是把流程过一遍。 一、原理图 实物是淘宝上stm32f103 c8t6的核心板,proteus上没有这个芯片,这里图上大概表示一下,用的是核心板自带的pc13引脚的led灯。 二、cubemxide配置 1.RCC如之前工程一样配置 2、配置SYS timebase Source不要使用systick,自己选择一个定时器,我这

qq_35442550的博客 7342

责任链模式实战:从if-else到优雅的校验链

在软件开发中,随着业务规则不断增多,if-else嵌套往往导致代码耦合严重、扩展困难,维护成本居高不下。设计模式中的责任链模式通过将多个处理者串联成链,让请求沿链传递,直到被合适的对象处理,从而实现了请求发送者与接收者的解耦。该模式天然符合开闭原则,新增处理逻辑只需追加节点,无需修改已有代码,因此在审批流、敏感词过滤、参数校验、风控规则引擎等场景中应用广泛。本文结合Java工程实践,深入拆解责任链模式的核心思想、两种实现方式(链表式与集合式),并通过一个完整的订单校验案例展示如何用责任链重构冗长的if-el

weixin_34208185的博客 313

手把手教你用Cesium和RayMarching实现逼真体积云(附完整Shader代码)

本文详细介绍了如何利用Cesium和RayMarching技术实现逼真的体积云效果,包括环境准备、核心逻辑、云层建模和光照增强等关键步骤,并提供了完整的Shader代码。通过噪声函数选型、动态风场模拟和多重散射近似等技术,开发者可以在数字地球可视化项目中创建沉浸式天气效果,显著提升场景的真实感。

weixin_29230649的博客 415

Windows 10下三菱PLC控件安装报错Error Number:-119的终极解决方案(附详细步骤)

本文针对Windows 10系统安装三菱PLC控件时常见的Error Number:-119报错,提供了深度分析与终极解决方案。文章剖析了该错误源于oleaut32.dll文件版本冲突,并详细介绍了通过设置兼容性模式、手动注册DLL、直接安装MX Component以及高级系统修复等多种方法,帮助用户彻底解决此安装难题,顺利搭建PLC开发环境。

weixin_29289821的博客 328

Java 23 种设计模式:从踩坑到精通 | 责任链模式 —— 请求流转,审批流程的本质

摘要:当请求需要经过多个处理者,且处理链在运行时才能确定时,写死 if-else 链会让代码严重耦合、难以扩展。责任链模式通过将处理者串联成一条链,让请求沿着链自动传递,直到被某个处理者处理。本文从 OA 审批流程出发,完整讲解纯责任链与不纯责任链的实现,结合 Servlet Filter、Spring Interceptor 等框架应用,并给出 Spring 自动装配链的实战写法,帮你彻底掌握“请求传递,各司其职”的设计精髓。

折哥|智能物流与Java实战,副高数据库工程师。深耕出版社物流WMS/OMS(线体/立库/VGA),也分享Java进阶与OMS电商对接。Oracle→PG实战派。相信沉淀可迁移能力,分享通用技术,不藏不虚。 955

经纬度转换为UTM坐标

UTM(通用横向墨卡托投影): 是一种以米为单位的坐标系统,用于地图和GPS导航。将地球划分为60个纵向的区域。每个区域宽6度,从赤道开始往南北两级方向划分。每个区域都有一个特定的字母。

weixin_45626706的博客 7275

责任链模式实战:从if-else泥潭到高扩展性审批流程设计

设计模式是解决复杂业务逻辑中代码腐化问题的有效工具,尤其当系统面临大量条件分支和规则频繁变更时,如何保持代码的可读性与可扩展性成为关键挑战。责任链模式(Chain of Responsibility)通过将请求沿链传递,让每个处理节点只关注自身职责,从而把“判断”和“处理”解耦,显著降低if-else嵌套带来的维护成本。该模式天然适用于审批流、过滤器链、风控校验等多级处理场景,既能动态调整节点顺序,又能轻松扩展新处理器,完美契合开闭原则。文章从一段典型的报销审批代码入手,剖析面条式if-else的坏味道,详

weixin_34082789的博客 415

即插即用系列(代码实践) | WACV 2024 CSAM:面向各向异性医学图像分割的 2.5D 跨切片注意力模块

文章摘要: 论文《CSAM: A 2.5D Cross-Slice Attention Module for Anisotropic Volumetric Medical Image Segmentation》提出了一种解决医学图像各向异性问题的创新模块CSAM。针对MRI/CT数据中切片间分辨率差异大的挑战,该模块通过2.5D跨切片注意力机制,结合2D卷积的轻量性和3D上下文感知能力。核心包括语义注意力(通道级)、位置注意力(空间级)和跨切片注意力(支持不确定性建模),能在几乎不增加参数量的情况下有效捕捉

分享顶会顶刊论文即插即用模块 104

基于3D相机的人体穴位识别与标注系统——完整Python实现方案

摘要 本文提出了一种基于3D相机的人体穴位识别与标注系统完整实现方案。系统采用Intel RealSense D435相机实时采集RGB-D数据,结合MediaPipe Pose模型进行人体33个关键骨骼点的三维姿态估计。通过建立穴位与骨骼关键点的映射关系,利用相机内参和深度信息将二维图像坐标转换为三维空间坐标。系统采用模块化设计,包含数据采集层、算法处理层、坐标转换层和可视化层,实现了穴位定位、三维坐标转换和点云可视化功能。关键技术包括:基于骨度折量法的穴位映射算法、深度图像到三维点云的转换方法,以及Op

AI的内部世界的博客 268

深度解析AI编码助手架构:从51万行源码看模块化设计与数据流实现

在AI工程化领域,大型语言模型与软件架构的融合正成为技术演进的关键方向。其核心原理在于通过模块化设计将传统静态分析与AI模型推理相结合,形成混合智能系统。这种架构的技术价值在于能够处理代码理解与生成中的不确定性,同时保证低延迟响应。在实际应用场景中,AI编码助手需要实现从上下文管理、意图识别到模型调用的完整数据流。本文以Claude Code的51万行源码为切入点,探讨其如何通过树解析器和语言服务器协议构建精准的代码上下文,并利用提示词工程基础设施化提升AI辅助编程的准确性与效率。

weixin_30791095的博客 337

【ESP32设备通信】-两个ESP32间UART通信

在本文中,我们将使用 Arduino IDE 的 UART 硬件库在两个 ESP32 板之间执行 UART 或串行通信。 要使用 USB 端口调试和编程 ESP32,需要使用称为通用异步接收器/发送器 (UART) 通信的串行端口。 对于大多数传感器和系统,主要的通信方法被认为是 UART。 为了共享工作负载、信息和执行不同的任务,有时需要在两个 ESP32 开发板之间进行通信。

视觉与物联智能 2991

23个设计模式一文搞懂

本笔记涵盖 23 种经典设计模式,按创建型、结构型、行为型三大类整理。每个模式配有生活类比、核心思想、结构图解、实现要点、真实应用案例、适用场景、优缺点分析及常见面试题。

weixin_72753562的博客 802

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

MyBatis详解八股文

Mybatismybatis简介什么是框架?为什么要用框架?Mybatis的发展史myBatis的优点Mybatis配置mybatis.xml配置文件 mybatis简介 MyBatis 是支持定制化 SQL以及高级映射(ORM)的优秀的持久层框架。 什么是框架?为什么要用框架? 1、框架即framework 其实就是某种应用的半成品,就是一组组件,供你选用完成自己的系统。 简单理解就是一套资源,包含jar包、源码、帮助文档、示例等 2、为什么要用框架 使用别人成熟的框架,就相当于让别人帮你完成一些基础工作

韩小兔修媛史的博客 230

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

《JAVA面经实录》- 23种设计模式面试题(二)

《JAVA设计模式面试精要》摘要:本文系统解析23种设计模式,分为创建型(单例、工厂等)、结构型(适配器、代理等)和行为型(观察者、策略等)三大类。重点阐述六大设计原则(SOLID+迪米特法则),每个模式均包含定义、原则应用、优缺点分析及典型业务场景(如电商支付、审批系统等),并附Java代码实现。特别强调模式选择需结合实际需求,避免过度设计,同时提供清晰的模式对比表格,帮助开发者快速掌握各模式核心特征与应用场景。

专注 Java 后端开发,分享基础语法、JVM、并发、Spring 全家桶、微服务、分布式、性能优化等实战干货。坚持输出高质量技术笔记,用简单语言讲清复杂原理,助力每一位 Java 开发者稳步进阶。 894

怎样设计一个好架构:八个评价维度、四层思考深度,以及 23 种设计模式各自解决什么问题

架构要解决的是变化、理解、故障和协作的成本。本文从耦合、可迁移、可适配、复杂度等八个维度讲怎么评价架构,讲维度之间怎么取舍、架构思考可以分几层,再用可编译的 C 代码过一遍 23 种设计模式。

weixin_52400878的博客 310

高扩展性AI应用架构指南:融合RAG检索、Agent编排与OpenAPI/RPC工具网关的设计模式

本文提出高扩展性AI应用的三层架构:RAG检索层(知识供给)、Agent编排层(决策推理)、工具网关层(能力执行)。通过检索策略路由实现智能分流,混合检索采用RRF融合算法提升精度;Agent层采用无状态设计与外部状态存储,支持水平扩展;工具网关层通过协议标准化与动态注册解耦系统。核心思想是各层独立演进,不相互牵制,实现从“能跑”到“可扩展”的工程跃迁。

2301_80078096的博客 183

设计模式速查

本文梳理12个核心设计模式,涵盖创建型、结构型与行为型,提供简洁Java实现与面试要点。重点解析单例(静态内部类)、工厂(方法/抽象)、建造者(链式构建)等高频模式,强调代码可维护性与扩展性,附速记口诀与对比表格,助力开发与面试双提升。

ttlovet的博客 157

设计模式与生活⑬:你坐几号线,谁来运营是另一回事

一到周五,小王的心情就会好一点。倒不是工作少了,而是想到这一天忙完,后面接着双休,心里就有盼头。地铁上,他抬头看标识,发现一件平时没留意的事:5 号线、10 号线常见的是“北京地铁”,4 号线却写着“京港地铁”。再想想,北京的机场也各有各的名字:首都机场、大兴机场。可在成都坐地铁,日常看到的统一称谓就是“成都地铁”。都是出行,名称和背后的主体并不完全一样。对乘客来说,常做的事还是那几样:查线路、进站、上车、到站下车。坐几号线是一条信息,谁来运营是另一条信息,不必揉成一团。同样是在北京坐地铁,线路和运营方并不

工一木子 214

【第四部分:Agentic 智能体设计模式】17. Agent 路由模式详解:从意图识别到动态模型选择

本文介绍 Agent Routing(路由模式)的基本原理与工程实现,重点分析任务路由、模型路由、工具路由和专业 Agent 路由的区别及适用场景。结合 BaseMetas EKA 企业知识助手,介绍规则与模型混合路由、Java Router 实现、复合任务处理、低置信度兜底和误路由评估,并以 Jev 专用决策模型、动态模型选择及 Tool Search 等近期技术为例,说明如何在保证权限与执行安全的前提下,提高 Agent 任务分发的准确性和效率。

weixin_42258782的博客 623

设计模式与生活⑭:一栋楼,共用一份热

今天是立冬。天气预报说夜里有暴雪,白天最高也就 4 度。早上起来,屋里比外面强不了多少。窗玻璃上蒙着一层水汽,摸一把暖气片,凉的。物业群里发了通知:今天开始试供暖,暖气片会慢慢热起来,顶层记得排气,边户留意自家热不热。隔了会儿再摸,暖气片上热下凉,温温的,不烫手。再晚一点,整间屋子总算有了点热乎气。一天里最踏实的一件事,是知道这栋楼里不只自己一户在等热。热力站烧的是一锅水,顺着管网送到每家,各家只管拧自己那个阀门。试供暖第一天,暖气片温而不烫今天聊的。

工一木子 311

设计模式与生活⑪:地铁里被打扰,别总靠自己硬扛

周三的地铁上,小王本来想在脑子里过一遍今天要做的事。旁边一位大哥戴着耳机打电话。耳机里对方说什么,别人听不见;大哥自己的声音,却一句一句落在外面。声音不算大,也没有嚷,可就是不停。你刚把那件事想到一半,旁边又接上一句;刚想不去留意,下一句又钻进来了。最磨人的不是哪一句特别响,而是你拿不准这通电话还要多久。小王没说什么,站起来,往车厢另一头挪了挪。距离拉开,思绪才慢慢接了回去。耳机收住了电话另一端的声音,收不住说话人的声音这让他想起之前的另一次经历。

工一木子 152

设计模式 - 访问者模式

概述 访问者模式(Visitor Pattern)是一种行为型设计模式,它通过为对象结构中的每个元素添加一个访问操作,使得可以在不改变元素类的前提下定义作用于这些元素的新操作。

2601_96797912的博客 175

工作流 vs 自主 Agent:5 种设计模式与 3 种建模方式详解

本文基于 Anthropic《Building Effective Agents》指南,系统梳理了AI应用中的两类核心架构:Workflow(编排式)与Agent(自主智能体)。强调“能画流程图就不上Agent”,提出从简单提示链到复杂自主决策的5种可组合工作流模式,并给出选型口诀与工程实践建议。核心观点:优先用确定性、可审计的Workflow,仅在任务路径未知时启用Agent,避免盲目复杂化。

分享大数据、java相关的技术 148

【QT C++】常用设计模式

保证一个类仅有一个实例,并提供一个访问它的全局访问点。

ocy的博客 231
上一篇: 14、(行为型设计模式)Java 观察者模式深度学习指南
下一篇: 16、(行为型设计模式)Java 命令模式深度学习指南
龙茶清欢
博客等级 码龄7年 3720粉丝 375原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

龙茶清欢

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值