异步请求框架

97 阅读13分钟

🏢 企业异步框架学习笔记

📚 目录

  1. 框架概述
  2. 核心设计理念
  3. 技术演进路径
  4. 框架核心组件
  5. 接口设计模式
  6. 生命周期管理
  7. Spring Boot 集成
  8. 实际应用场景
  9. 最佳实践

🎯 框架概述

什么是企业级异步框架?

企业级异步框架是在 Future submit + get 基础上,通过标准化接口设计,将异步调用的完整生命周期进行抽象和统一管理的框架。

🔥 核心价值

  • 标准化流程 - 统一异步调用的生命周期管理
  • 接口抽象 - 面向接口编程,支持无限扩展
  • 企业级治理 - 监控、超时、降级等企业级特性
  • 开发效率 - 减少重复代码,提升开发效率

💡 核心设计理念

1. 本质分析

// 基础层:Future 的 submit + get 模式
Future<Result> future = executor.submit(() -> doSomething());
Result result = future.get(); // 阻塞等待结果

// 企业级框架:标准化 + 流程化
🚪 access()  → 准入检查    → 决定是否执行
📦 build()   → 构建请求    → 标准化参数构建
🚀 action()  → 执行调用    → 实际的 submit + get
🎯 show()    → 准出检查    → 决定是否展示结果
📋 pack()    → 打包结果    → 标准化结果处理

2. 设计原则

  • 面向接口编程 - 依赖抽象,不依赖具体
  • 统一流程管理 - 标准化异步调用生命周期
  • 可扩展性 - 新增服务无需修改框架代码
  • 企业级特性 - 监控、治理、降级等

🚀 技术演进路径

第一阶段:传统 Future 方式

// ❌ 传统方式 - 手动管理,代码冗余
ExecutorService executor = Executors.newFixedThreadPool(10);

FutureTask<UserInfo> userTask = new FutureTask<>(() -> {
    return userService.getUserInfo(userId);
});
executor.submit(userTask);

UserInfo userInfo = userTask.get(); // 阻塞等待
executor.shutdown(); // 手动关闭

第二阶段:CompletableFuture 优化

// ✅ CompletableFuture - 现代异步编程
CompletableFuture<UserInfo> userFuture = CompletableFuture.supplyAsync(() ->
    userService.getUserInfo(userId)
);

CompletableFuture<MedalInfo> medalFuture = CompletableFuture.supplyAsync(() ->
    medalService.getMedalInfo(userId)
);

// 组合结果
CompletableFuture<String> result = userFuture.thenCombine(medalFuture,
    (user, medal) -> "用户: " + user + ", 勋章: " + medal
);

第三阶段:企业级异步框架

// 🏢 企业级框架 - 标准化 + 统一管理
asyncActionService.submitRemoteCall(userInfoCall, carrier);
asyncActionService.submitRemoteCall(medalInfoCall, carrier);

UserInfo user = asyncActionService.getRemoteCallResult(userInfoCall, carrier);
MedalInfo medal = asyncActionService.getRemoteCallResult(medalInfoCall, carrier);

🔧 框架核心组件

1. 核心接口 - IRemoteCall

public interface IRemoteCall<REQUEST, RESPONSE, CARRIER> {
    String type();                                    // 🏷️ 服务标识
    int timeout();                                   // ⏰ 超时时间
    boolean access(CARRIER carrier);                 // 🚪 准入检查
    REQUEST build(CARRIER carrier);                  // 📦 构建请求
    RESPONSE action(REQUEST request, CARRIER carrier); // 🚀 执行调用
    boolean show(CARRIER carrier);                   // 🎯 准出检查
    RESPONSE pack(CARRIER carrier);                  // 📋 打包结果
}

2. 异步行动服务 - AsyncActionService

@Service
public class AsyncActionService {

    // 🎯 提交异步任务:~= Future<Result> future = executor.submit(() -> doSomething()); 
    public <REQUEST, RESPONSE> CompletableFuture<RESPONSE> submitRemoteCall(
            IRemoteCall<REQUEST, RESPONSE, InfoCarrier> remoteCall,
            InfoCarrier infoCarrier) {
        // 统一的异步处理逻辑
    }

    // 🎯 获取异步结果:~= Result result = future.get(); // 阻塞等待结果
    public <RESPONSE> RESPONSE getRemoteCallResult(
            IRemoteCall<?, RESPONSE, InfoCarrier> remoteCall,
            InfoCarrier infoCarrier) {
        // 统一的结果获取逻辑
    }
}

===vs===

// 最基础的异步模式 
Future<Result> future = executor.submit(() -> doSomething()); 
Result result = future.get(); // 阻塞等待结果

eg:

package framework;

import java.util.Objects;
import java.util.concurrent.*;

/**
 * 异步行动服务 - 企业级异步框架核心
 * 🚀 基于 CompletableFuture 的现代化实现
 */
public class AsyncActionService {

    // 自定义线程池,模仿企业级配置
    private static final ExecutorService executorService = Executors.newFixedThreadPool(
        Runtime.getRuntime().availableProcessors() * 2,
        r -> {
            Thread t = new Thread(r, "async-action-" + System.currentTimeMillis());
            t.setDaemon(true);
            return t;
        }
    );

    /**
     * 🎯 提交远程调用任务
     */
    public <REQUEST, RESPONSE> CompletableFuture<RESPONSE> submitRemoteCall(
            IRemoteCall<REQUEST, RESPONSE, InfoCarrier> remoteCall,
            InfoCarrier infoCarrier) {

        String type = remoteCall.type();
        System.out.println("🚀 提交异步任务: " + type);

        // 记录任务开始时间
        infoCarrier.getStartTimeMap().put(type, System.currentTimeMillis());

        CompletableFuture<RESPONSE> future = CompletableFuture
            .supplyAsync(() -> {
                try {
                    // 1. 准入条件检查
                    if (!remoteCall.access(infoCarrier)) {
                        System.out.println("❌ " + type + " 准入条件不满足");
                        return null;
                    }

                    // 2. 构建请求参数
                    REQUEST request = remoteCall.build(infoCarrier);
                    System.out.println("📦 " + type + " 请求参数构建完成");

                    // 3. 执行远程调用
                    RESPONSE response = remoteCall.action(request, infoCarrier);
                    System.out.println("✅ " + type + " 调用成功");

                    return response;

                } catch (Exception e) {
                    System.err.println("💥 " + type + " 调用失败: " + e.getMessage());
                    throw new RuntimeException(e);
                }
            }, executorService)
            .orTimeout(remoteCall.timeout(), TimeUnit.MILLISECONDS)
            .handle((result, ex) -> {
                if (ex != null) {
                    if (ex instanceof TimeoutException) {
                        System.err.println("⏰ " + type + " 调用超时");
                    } else {
                        System.err.println("💥 " + type + " 调用异常: " + ex.getMessage());
                    }
                    return null; // 异常时返回null,实现降级
                }
                return result;
            })
            .whenComplete((result, ex) -> {
                // 监控埋点 - 记录调用耗时
                long costTime = System.currentTimeMillis() - infoCarrier.getStartTimeMap().get(type);
                System.out.println("📊 " + type + " 耗时: " + costTime + "ms");

                // 存储结果到载体中
                if (result != null) {
                    infoCarrier.addServiceResponse(type, result);
                }
            });

        // 将Future存储到载体中,供后续获取
        infoCarrier.getFutureMap().put(type, future);

        return future;
    }

    /**
     * 🎯 获取远程调用结果 - 完整版(包含准出和打包)
     */
    @SuppressWarnings("unchecked")
    public <RESPONSE> RESPONSE getRemoteCallResult(IRemoteCall<?, RESPONSE, InfoCarrier> remoteCall,
                                                   InfoCarrier infoCarrier) {
        String type = remoteCall.type();
        Future<RESPONSE> future = (Future<RESPONSE>) infoCarrier.getFutureMap().get(type);

        if (Objects.isNull(future)) {
            System.out.println("⚠️ " + type + " 任务未找到");
            return null;
        }

        try {
            System.out.println("⏳ 等待 " + type + " 结果...");
            RESPONSE result = future.get(); // 阻塞等待结果

            if (result != null) {
                System.out.println("✅ " + type + " 获取结果成功");

                // 🎯 准出条件检查
                if (remoteCall.show(infoCarrier)) {
                    System.out.println("🎯 " + type + " 通过准出条件检查");
                    // 📋 打包结果
                    RESPONSE packedResult = remoteCall.pack(infoCarrier);
                    return packedResult;
                } else {
                    System.out.println("🚫 " + type + " 未通过准出条件,不展示结果");
                    return null;
                }
            } else {
                System.out.println("⚠️ " + type + " 结果为空(可能超时或异常)");
                return null;
            }

        } catch (Exception e) {
            System.err.println("💥 获取 " + type + " 结果失败: " + e.getMessage());
            return null;
        }
    }

    /**
     * 🎯 获取远程调用结果 - 简化版(向后兼容)
     */
    @SuppressWarnings("unchecked")
    public <RESPONSE> RESPONSE getRemoteCallResult(String type, InfoCarrier infoCarrier) {
        Future<RESPONSE> future = (Future<RESPONSE>) infoCarrier.getFutureMap().get(type);

        if (Objects.isNull(future)) {
            System.out.println("⚠️ " + type + " 任务未找到");
            return null;
        }

        try {
            System.out.println("⏳ 等待 " + type + " 结果...");
            RESPONSE result = future.get(); // 阻塞等待结果

            if (result != null) {
                System.out.println("🎉 " + type + " 获取结果成功");
            } else {
                System.out.println("⚠️ " + type + " 结果为空(可能超时或异常)");
            }

            return result;

        } catch (Exception e) {
            System.err.println("💥 获取 " + type + " 结果失败: " + e.getMessage());
            return null;
        }
    }

    /**
     * 🎯 批量等待多个任务完成
     */
    public void waitAllTasks(InfoCarrier infoCarrier, String... types) {
        System.out.println("⏳ 等待所有任务完成: " + String.join(", ", types));

        CompletableFuture<?>[] futures = new CompletableFuture[types.length];
        for (int i = 0; i < types.length; i++) {
            futures[i] = (CompletableFuture<?>) infoCarrier.getFutureMap().get(types[i]);
        }

        CompletableFuture.allOf(futures).join();
        System.out.println("🎉 所有任务执行完成!");
    }

    /**
     * 🎯 关闭线程池
     */
    public static void shutdown() {
        executorService.shutdown();
        System.out.println("🔚 异步服务已关闭");
    }
}

3. 信息载体 - InfoCarrier

public class InfoCarrier {
    private Long userId;                                    // 用户ID
    private Map<String, Future<?>> futureMap;              // 异步任务存储
    private Map<String, Object> responseMap;               // 响应结果存储
    private Map<String, Long> startTimeMap;                // 监控时间存储

    public void addServiceResponse(String type, Object response);
    public <T> T getServiceResponse(String type);
}

🎭 接口设计模式

面向接口编程的威力

// 🔥 一个方法支持无数种实现
public <REQUEST, RESPONSE> CompletableFuture<RESPONSE> submitRemoteCall(
    IRemoteCall<REQUEST, RESPONSE, InfoCarrier> remoteCall,  // 接口类型入参
    InfoCarrier infoCarrier
) {
    // 框架只关心接口,不关心具体实现
    String type = remoteCall.type();           // 多态调用
    boolean canAccess = remoteCall.access();   // 多态调用
    REQUEST request = remoteCall.build();      // 多态调用
}

扩展性展示

// 任何实现了接口的类都可以使用同一个框架方法
asyncActionService.submitRemoteCall(userInfoCall, carrier);     // 用户信息
asyncActionService.submitRemoteCall(medalInfoCall, carrier);    // 勋章信息
asyncActionService.submitRemoteCall(orderInfoCall, carrier);    // 订单信息
asyncActionService.submitRemoteCall(paymentCall, carrier);      // 支付信息
asyncActionService.submitRemoteCall(couponCall, carrier);       // 优惠券信息
// ... 新增服务无需修改框架代码

实现示例

@Component
public class UserInfoRemoteCall implements IRemoteCall<Long, UserInfo, InfoCarrier> {

    @Autowired
    private UserInfoService userInfoService; // 🔥 Spring 依赖注入

    @Override
    public String type() { return "USER_INFO"; }

    @Override
    public boolean access(InfoCarrier carrier) {
        return carrier.getUserId() != null; // 准入条件
    }

    @Override
    public Long build(InfoCarrier carrier) {
        return carrier.getUserId(); // 构建请求参数
    }

    @Override
    public UserInfo action(Long userId, InfoCarrier carrier) throws Exception {
        return userInfoService.getUserInfo(userId); // 实际调用
    }

    @Override
    public boolean show(InfoCarrier carrier) {
        UserInfo user = carrier.getServiceResponse(type());
        return user != null && user.getUserName() != null; // 准出条件
    }

    @Override
    public UserInfo pack(InfoCarrier carrier) {
        return carrier.getServiceResponse(type()); // 打包结果
    }
}

🔄 生命周期管理

完整的异步调用生命周期

🚪 准入检查 → 📦 构建请求 → 🚀 异步执行 → 🎯 准出检查 → 📋 打包结果

1. 准入阶段 (access) 🚪

作用: 在执行前判断是否需要调用该服务 场景:

  • 用户权限检查
  • 功能开关控制
  • 业务规则过滤
@Override
public boolean access(InfoCarrier carrier) {
    // 只有登录用户才获取用户信息
    return carrier.getUserId() != null;
}

2. 构建阶段 (build) 📦

作用: 根据上下文构建请求参数 场景:

  • 参数转换
  • 默认值设置
  • 请求封装
@Override
public Long build(InfoCarrier carrier) {
    return carrier.getUserId(); // 提取用户ID作为请求参数
}

3. 执行阶段 (action) 🚀

作用: 实际的远程服务调用 场景:

  • HTTP调用
  • RPC调用
  • 数据库查询
@Override
public UserInfo action(Long userId, InfoCarrier carrier) throws Exception {
    return userInfoService.getUserInfo(userId);
}

4. 准出阶段 (show) 🎯

作用: 在返回前判断是否展示该结果 场景:

  • 结果有效性检查
  • 业务规则过滤
  • 权限二次校验
@Override
public boolean show(InfoCarrier carrier) {
    UserInfo user = carrier.getServiceResponse(type());
    return user != null && user.isVip(); // 只有VIP用户才展示详细信息
}

5. 打包阶段 (pack) 📋

作用: 对结果进行最终包装和处理 场景:

  • 数据脱敏
  • 格式转换
  • 字段过滤
@Override
public UserInfo pack(InfoCarrier carrier) {
    UserInfo user = carrier.getServiceResponse(type());
    // 可以在这里进行数据脱敏等处理
    return user;
}

🌱 Spring Boot 集成

1. 依赖注入优势

// ❌ 传统方式 - 手动管理依赖
UserInfoService userInfoService = new UserInfoService();
AsyncActionService actionService = new AsyncActionService();
UserInfoRemoteCall userCall = new UserInfoRemoteCall(userInfoService);

// ✅ Spring Boot + @Autowired - 自动依赖注入
@Autowired
private UserInfoService userInfoService;

@Autowired
private AsyncActionService asyncActionService;

@Autowired
private UserInfoRemoteCall userInfoRemoteCall;

2. 注解体系

@Service                    // 业务服务层
public class UserInfoService { }

@Component                  // 远程调用组件
public class UserInfoRemoteCall implements IRemoteCall<...> { }

@RestController            // Web控制器
public class AsyncDemoController { }

@SpringBootApplication     // 主启动类
@EnableAsync              // 启用异步支持
public class AsyncFrameworkApplication { }

3. 项目结构

src/main/java/com/example/async/
├── AsyncFrameworkApplication.java     # 🚀 Spring Boot 主启动类
├── controller/
│   └── AsyncDemoController.java       # 🎮 REST API 控制器
├── framework/
│   ├── AsyncActionService.java        # 🔧 异步行动服务 (@Service)
│   ├── IRemoteCall.java              # 📋 远程调用接口
│   └── InfoCarrier.java              # 📦 信息载体
├── model/
│   ├── UserInfo.java                 # 👤 用户信息实体
│   └── MedalInfo.java                # 🏅 勋章信息实体
├── remotecall/
│   ├── UserInfoRemoteCall.java       # 👤 用户信息远程调用 (@Component)
│   └── MedalInfoRemoteCall.java      # 🏅 勋章信息远程调用 (@Component)
├── runner/
│   └── AsyncFrameworkRunner.java     # 🏃‍♂️ 启动演示运行器
└── service/
    ├── UserInfoService.java          # 👤 用户信息服务 (@Service)
    └── MedalService.java             # 🏅 勋章服务 (@Service)

为啥要有框架?

没有框架时,每个异步调用都要重复写相同的逻辑。异步框架相当于将重复逻辑抽象成一套框架,rd 仅需关注业务开发。

  • 没有框架:主流程充斥着各种 if 以及业务逻辑;
  • 有框架:主流程仅有 submit&get,重点突出remoteCall,业务代码收敛至各Service;

🔴 没有框架时的问题

看附录第一部分的代码,每个服务调用都要重复写:

// 🔥 重复代码模板 - 每个服务都要写一遍
if (userId != null) {  // 准入检查 - 重复!
    Future<String> future = executor.submit(() -> {
        String request = "userId=" + userId;  // 构建请求 - 重复!
        // 执行具体调用...
        return result;
    });
    
    String result = future.get();  // 获取结果 - 重复!
    if (result != null && !result.isEmpty()) {  // 准出检查 - 重复!
        String processed = "处理后的" + result;  // 结果处理 - 重复!
        // ...
    }
}

问题

  1. 用户信息服务 - 写了一遍完整流程
  2. 订单信息服务 - 又写了一遍几乎相同的流程
  3. 支付信息服务 - 再写了一遍几乎相同的流程
  4. 如果有10个服务 - 就要写10遍相同的流程!

🟢 有框架时的解决方案

看附录第二部分的代码,所有服务调用都用同一个方法:

// 🔥 统一处理 - 一个方法处理所有服务
framework.executeServiceCall(userCall, context);    // 用户服务
framework.executeServiceCall(orderCall, context);   // 订单服务  
framework.executeServiceCall(paymentCall, context); // 支付服务

优势

  1. 消除重复 - 流程代码只写一遍
  2. 统一管理 - 所有服务都用相同的处理逻辑
  3. 易于维护 - 修改流程只需改一处
  4. 易于扩展 - 新增服务只需实现接口

附录

import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

/**
 * 🎯 重复代码问题演示
 * 展示没有框架时,每个异步调用都要重复写相同的逻辑
 */
public class RepetitiveCodeDemo {

    private static ExecutorService executor = Executors.newFixedThreadPool(4);

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        System.out.println("🎯 === 重复代码问题演示 === 🎯\n");

        // ========== 第一部分:没有框架的重复代码 ==========
        System.out.println("📋 第一部分:没有框架 - 每个服务都要重复写相同逻辑");
        withoutFrameworkDemo();

        System.out.println("\n" + "=".repeat(60) + "\n");

        // ========== 第二部分:有框架的统一处理 ==========
        System.out.println("📋 第二部分:有框架 - 统一处理,消除重复");
        withFrameworkDemo();

        executor.shutdown();
    }

    // 没有框架:每个服务调用都要重复写相同的逻辑
    static void withoutFrameworkDemo() throws ExecutionException, InterruptedException {
        Long userId = 666L;

        System.out.println("🔴 问题:每个异步调用都要重复写相同的模板代码\n");

        // ========== 调用用户信息服务 ==========
        System.out.println("1️⃣ 调用用户信息服务:");

        // 🔥 重复代码块 1
        if (userId != null) {  // 准入检查
            System.out.println("  ✅ 用户信息服务准入检查通过");

            Future<String> userFuture = executor.submit(() -> {
                // 构建请求参数
                String request = "userId=" + userId;
                System.out.println("  📦 构建用户信息请求: " + request);

                // 执行调用
                try {
                    Thread.sleep(2000); // 模拟网络调用
                    return "用户信息:张三,VIP用户";
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            });

            String userResult = userFuture.get();
            if (userResult != null && !userResult.isEmpty()) {  // 准出检查
                System.out.println("  🎯 用户信息准出检查通过");
                String processedResult = "处理后的" + userResult;  // 结果处理
                System.out.println("  📋 用户信息最终结果: " + processedResult);
            } else {
                System.out.println("  ❌ 用户信息准出检查失败");
            }
        } else {
            System.out.println("  ❌ 用户信息服务准入检查失败");
        }

        System.out.println();

        // ========== 调用订单信息服务 ==========
        System.out.println("2️⃣ 调用订单信息服务:");

        // 🔥 重复代码块 2 - 几乎一模一样的逻辑!
        if (userId != null) {  // 准入检查 - 重复!
            System.out.println("  ✅ 订单信息服务准入检查通过");

            Future<String> orderFuture = executor.submit(() -> {
                // 构建请求参数 - 重复!
                String request = "userId=" + userId;
                System.out.println("  📦 构建订单信息请求: " + request);

                // 执行调用 - 重复!
                try {
                    Thread.sleep(1000); // 模拟网络调用
                    return "订单信息:订单123,已支付";
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            });

            String orderResult = orderFuture.get();
            if (orderResult != null && !orderResult.isEmpty()) {  // 准出检查 - 重复!
                System.out.println("  🎯 订单信息准出检查通过");
                String processedResult = "处理后的" + orderResult;  // 结果处理 - 重复!
                System.out.println("  📋 订单信息最终结果: " + processedResult);
            } else {
                System.out.println("  ❌ 订单信息准出检查失败");
            }
        } else {
            System.out.println("  ❌ 订单信息服务准入检查失败");
        }

        System.out.println();

        // ========== 调用支付信息服务 ==========
        System.out.println("3️⃣ 调用支付信息服务:");

        // 🔥 重复代码块 3 - 又是几乎一模一样的逻辑!
        if (userId != null) {  // 准入检查 - 又重复!
            System.out.println("  ✅ 支付信息服务准入检查通过");

            Future<String> paymentFuture = executor.submit(() -> {
                // 构建请求参数 - 又重复!
                String request = "userId=" + userId;
                System.out.println("  📦 构建支付信息请求: " + request);

                // 执行调用 - 又重复!
                try {
                    Thread.sleep(500); // 模拟网络调用
                    return "支付信息:支付宝,余额100元";
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            });

            String paymentResult = paymentFuture.get();
            if (paymentResult != null && !paymentResult.isEmpty()) {  // 准出检查 - 又重复!
                System.out.println("  🎯 支付信息准出检查通过");
                String processedResult = "处理后的" + paymentResult;  // 结果处理 - 又重复!
                System.out.println("  📋 支付信息最终结果: " + processedResult);
            } else {
                System.out.println("  ❌ 支付信息准出检查失败");
            }
        } else {
            System.out.println("  ❌ 支付信息服务准入检查失败");
        }

        System.out.println("\n🔴 问题总结:");
        System.out.println("1. 每个服务调用都要写:准入检查 → 构建请求 → 执行调用 → 准出检查 → 结果处理");
        System.out.println("2. 代码重复率极高,只有具体的业务逻辑不同");
        System.out.println("3. 如果要修改流程(比如加超时控制),需要改N个地方");
        System.out.println("4. 容易出错,维护困难");
    }

    // 有框架:统一处理,消除重复
    static void withFrameworkDemo() {
        Long userId = 666L;

        System.out.println("🟢 解决方案:使用框架统一处理,消除重复代码\n");

        // 创建框架和上下文
        SimpleFramework framework = new SimpleFramework();
        RequestContext context = new RequestContext(userId);

        // 创建不同的服务调用实现
        ServiceCall userCall = new UserInfoServiceCall();
        ServiceCall orderCall = new OrderInfoServiceCall();
        ServiceCall paymentCall = new PaymentInfoServiceCall();

        System.out.println("🔥 关键:同一个框架方法处理所有服务调用");

        // 🔥 同一个方法,处理不同的服务 - 没有重复代码!
        framework.executeServiceCall(userCall, context);
        System.out.println();

        framework.executeServiceCall(orderCall, context);
        System.out.println();

        framework.executeServiceCall(paymentCall, context);
        System.out.println();

        System.out.println("🟢 框架优势:");
        System.out.println("1. 统一的处理流程,消除重复代码");
        System.out.println("2. 新增服务只需实现接口,无需重写流程");
        System.out.println("3. 修改流程只需改框架一处,所有服务自动生效");
        System.out.println("4. 代码清晰,易于维护和测试");
    }
}

// ========== 没有框架时的重复代码问题 ==========
// 上面的 withoutFrameworkDemo 方法已经展示了重复代码的问题

// ========== 框架解决方案 ==========

// 服务调用接口
interface ServiceCall {
    String getServiceName();
    boolean checkAccess(RequestContext context);
    String buildRequest(RequestContext context);
    String executeCall(String request) throws InterruptedException;
    boolean checkResult(String result);
    String processResult(String result);
}

// 请求上下文
class RequestContext {
    private Long userId;

    public RequestContext(Long userId) {
        this.userId = userId;
    }

    public Long getUserId() {
        return userId;
    }
}

// 简单框架 - 统一处理所有服务调用
class SimpleFramework {
    private ExecutorService executor = Executors.newFixedThreadPool(4);

    // 🔥 统一的服务调用方法 - 消除重复代码
    public void executeServiceCall(ServiceCall serviceCall, RequestContext context) {
        String serviceName = serviceCall.getServiceName();
        System.out.println("🚀 执行服务调用: " + serviceName);

        try {
            // 1. 准入检查 - 统一处理
            if (!serviceCall.checkAccess(context)) {
                System.out.println("  ❌ " + serviceName + " 准入检查失败");
                return;
            }
            System.out.println("  ✅ " + serviceName + " 准入检查通过");

            // 2. 构建请求 - 统一处理
            String request = serviceCall.buildRequest(context);
            System.out.println("  📦 构建请求: " + request);

            // 3. 异步执行 - 统一处理
            Future<String> future = executor.submit(() -> {
                return serviceCall.executeCall(request);
            });

            String result = future.get();

            // 4. 准出检查 - 统一处理
            if (!serviceCall.checkResult(result)) {
                System.out.println("  ❌ " + serviceName + " 准出检查失败");
                return;
            }
            System.out.println("  🎯 " + serviceName + " 准出检查通过");

            // 5. 结果处理 - 统一处理
            String finalResult = serviceCall.processResult(result);
            System.out.println("  📋 " + serviceName + " 最终结果: " + finalResult);

        } catch (Exception e) {
            System.out.println("  💥 " + serviceName + " 执行异常: " + e.getMessage());
        }
    }
}

// 用户信息服务实现
class UserInfoServiceCall implements ServiceCall {
    @Override
    public String getServiceName() {
        return "用户信息服务";
    }

    @Override
    public boolean checkAccess(RequestContext context) {
        return context.getUserId() != null;
    }

    @Override
    public String buildRequest(RequestContext context) {
        return "userId=" + context.getUserId();
    }

    @Override
    public String executeCall(String request) throws InterruptedException {
        Thread.sleep(2000); // 模拟网络调用
        return "用户信息:张三,VIP用户";
    }

    @Override
    public boolean checkResult(String result) {
        return result != null && !result.isEmpty();
    }

    @Override
    public String processResult(String result) {
        return "处理后的" + result;
    }
}

// 订单信息服务实现
class OrderInfoServiceCall implements ServiceCall {
    @Override
    public String getServiceName() {
        return "订单信息服务";
    }

    @Override
    public boolean checkAccess(RequestContext context) {
        return context.getUserId() != null;
    }

    @Override
    public String buildRequest(RequestContext context) {
        return "userId=" + context.getUserId();
    }

    @Override
    public String executeCall(String request) throws InterruptedException {
        Thread.sleep(1000); // 模拟网络调用
        return "订单信息:订单123,已支付";
    }

    @Override
    public boolean checkResult(String result) {
        return result != null && !result.isEmpty();
    }

    @Override
    public String processResult(String result) {
        return "处理后的" + result;
    }
}

// 支付信息服务实现
class PaymentInfoServiceCall implements ServiceCall {
    @Override
    public String getServiceName() {
        return "支付信息服务";
    }

    @Override
    public boolean checkAccess(RequestContext context) {
        return context.getUserId() != null;
    }

    @Override
    public String buildRequest(RequestContext context) {
        return "userId=" + context.getUserId();
    }

    @Override
    public String executeCall(String request) throws InterruptedException {
        Thread.sleep(500); // 模拟网络调用
        return "支付信息:支付宝,余额100元";
    }

    @Override
    public boolean checkResult(String result) {
        return result != null && !result.isEmpty();
    }

    @Override
    public String processResult(String result) {
        return "处理后的" + result;
    }
}