手把手教你写 httpclient 框架(三)- 动态代理与请求处理机制

前言

在前两篇文章中,我们分别介绍了框架的整体架构设计和核心注解系统。从本篇开始,我们将深入到框架的核心实现 ------ 动态代理机制。

动态代理是整个框架的心脏,它负责:

  • 拦截用户的方法调用
  • 解析方法上的注解信息
  • 构建 HTTP 请求
  • 执行拦截器链
  • 调用底层 HTTP 客户端
  • 处理响应结果

理解动态代理机制对于掌握框架的工作原理至关重要。

动态代理基础知识

什么是动态代理?

动态代理是 Java 反射机制的一个重要应用,它允许我们在运行时创建一个实现了指定接口的代理对象。当调用代理对象的方法时,会被转发到 InvocationHandlerinvoke 方法中处理。

为什么选择动态代理?

  1. 无需实现类:用户只需定义接口,框架自动生成实现
  2. 统一处理:所有方法调用都会经过同一个处理器
  3. 灵活性强:可以根据方法信息动态决定处理逻辑
  4. AOP 支持:天然支持切面编程

动态代理的基本用法

java 复制代码
// 1. 定义接口
public interface UserService {
    String getUser(Long id);
}

// 2. 实现 InvocationHandler
public class UserServiceHandler implements InvocationHandler {
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("调用方法:" + method.getName());
        // 这里可以添加自定义逻辑
        return "User-" + args[0];
    }
}

// 3. 创建代理对象
UserService userService = (UserService) Proxy.newProxyInstance(
    UserService.class.getClassLoader(),
    new Class[]{UserService.class},
    new UserServiceHandler()
);

// 4. 调用方法
String user = userService.getUser(1L);  // 输出:调用方法:getUser

HttpClientFactory 实现

让我们从框架的入口 HttpClientFactory 开始:

java 复制代码
package io.github.nemoob.httpclient;

import com.fasterxml.jackson.databind.ObjectMapper;
import io.github.nemoob.httpclient.annotation.HttpClient;
import io.github.nemoob.httpclient.annotation.Interceptor;

import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * HTTP客户端工厂类
 * 负责创建HTTP客户端代理对象
 */
public class HttpClientFactory {
    // 全局对象映射器
    private static final ObjectMapper objectMapper = new ObjectMapper();
    
    // 默认线程池
    private static final ExecutorService defaultExecutor = Executors.newCachedThreadPool();
    
    // 全局拦截器列表
    private static final List<RequestInterceptor> globalInterceptors = new ArrayList<>();
    
    /**
     * 创建HTTP客户端代理对象
     * @param clientClass 客户端接口类
     * @return 代理对象
     */
    @SuppressWarnings("unchecked")
    public static <T> T create(Class<T> clientClass) {
        // 1. 验证接口定义
        validateInterface(clientClass);
        
        // 2. 获取@HttpClient注解信息
        HttpClient httpClientAnnotation = clientClass.getAnnotation(HttpClient.class);
        
        // 3. 创建底层HTTP客户端
        SimpleHttpClient httpClient = createHttpClient(httpClientAnnotation);
        
        // 4. 获取类级别拦截器
        List<RequestInterceptor> classInterceptors = getClassInterceptors(clientClass);
        
        // 5. 创建调用处理器
        HttpClientInvocationHandler handler = new HttpClientInvocationHandler(
            httpClient,
            httpClientAnnotation.async(),
            httpClientAnnotation.executor(),
            combineInterceptors(globalInterceptors, classInterceptors)
        );
        
        // 6. 创建动态代理对象
        return (T) Proxy.newProxyInstance(
            clientClass.getClassLoader(),
            new Class[]{clientClass},
            handler
        );
    }
    
    /**
     * 验证接口定义的正确性
     */
    private static void validateInterface(Class<?> clientClass) {
        if (!clientClass.isInterface()) {
            throw new IllegalArgumentException("Only interfaces are supported");
        }
        
        if (!clientClass.isAnnotationPresent(HttpClient.class)) {
            throw new IllegalArgumentException("Interface must be annotated with @HttpClient");
        }
    }
    
    /**
     * 创建底层HTTP客户端
     */
    private static SimpleHttpClient createHttpClient(HttpClient annotation) {
        SimpleHttpClient httpClient = new SimpleHttpClient();
        
        // 设置基础URL
        String baseUrl = annotation.baseUrl().isEmpty() ? annotation.value() : annotation.baseUrl();
        httpClient.setBaseUrl(baseUrl);
        
        // 设置超时时间
        httpClient.setConnectTimeout(annotation.connectTimeout());
        httpClient.setReadTimeout(annotation.readTimeout());
        
        return httpClient;
    }
    
    /**
     * 获取类级别拦截器
     */
    private static List<RequestInterceptor> getClassInterceptors(Class<?> clientClass) {
        List<RequestInterceptor> interceptors = new ArrayList<>();
        
        if (clientClass.isAnnotationPresent(Interceptor.class)) {
            Interceptor interceptorAnnotation = clientClass.getAnnotation(Interceptor.class);
            for (Class<? extends RequestInterceptor> interceptorClass : interceptorAnnotation.value()) {
                try {
                    interceptors.add(interceptorClass.newInstance());
                } catch (Exception e) {
                    throw new RuntimeException("Failed to create interceptor: " + interceptorClass.getName(), e);
                }
            }
        }
        
        return interceptors;
    }
    
    /**
     * 合并全局拦截器和类级别拦截器
     */
    private static List<RequestInterceptor> combineInterceptors(
            List<RequestInterceptor> global, 
            List<RequestInterceptor> classLevel) {
        List<RequestInterceptor> combined = new ArrayList<>(global);
        combined.addAll(classLevel);
        return combined;
    }
    
    // 其他工具方法...
    public static ObjectMapper getObjectMapper() {
        return objectMapper;
    }
    
    public static ExecutorService getDefaultExecutor() {
        return defaultExecutor;
    }
    
    public static void addGlobalInterceptor(RequestInterceptor interceptor) {
        globalInterceptors.add(interceptor);
    }
}

HttpClientInvocationHandler 核心实现

HttpClientInvocationHandler 是动态代理的核心,负责处理所有方法调用:

java 复制代码
package io.github.nemoob.httpclient;

import com.fasterxml.jackson.databind.ObjectMapper;
import io.github.nemoob.httpclient.annotation.*;

import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * HTTP客户端调用处理器
 * 负责拦截方法调用并转换为HTTP请求
 */
public class HttpClientInvocationHandler implements InvocationHandler {
    
    private final SimpleHttpClient httpClient;
    private final boolean defaultAsync;
    private final String defaultExecutorName;
    private final List<RequestInterceptor> globalInterceptors;
    private final ObjectMapper objectMapper;
    
    // 路径参数正则表达式
    private static final Pattern PATH_PARAM_PATTERN = Pattern.compile("\\{([^}]+)\\}");
    
    public HttpClientInvocationHandler(SimpleHttpClient httpClient, 
                                     boolean defaultAsync, 
                                     String defaultExecutorName,
                                     List<RequestInterceptor> globalInterceptors) {
        this.httpClient = httpClient;
        this.defaultAsync = defaultAsync;
        this.defaultExecutorName = defaultExecutorName;
        this.globalInterceptors = globalInterceptors != null ? globalInterceptors : new ArrayList<>();
        this.objectMapper = HttpClientFactory.getObjectMapper();
    }
    
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        // 处理Object类的方法(toString, equals, hashCode等)
        if (method.getDeclaringClass() == Object.class) {
            return method.invoke(this, args);
        }
        
        // 创建请求上下文
        DefaultRequestContext context = createRequestContext(method, args);
        
        try {
            // 执行拦截器链
            executeInterceptors(context, true);
            
            // 如果拦截器已经设置了响应,直接返回
            if (context.getResponse() != null) {
                return handleResponse(context, method);
            }
            
            // 构建HTTP请求
            HttpRequest request = buildHttpRequest(method, args);
            context.setRequest(request);
            
            // 判断是否异步执行
            boolean isAsync = shouldExecuteAsync(method);
            
            if (isAsync) {
                return executeAsync(context, method);
            } else {
                return executeSync(context, method);
            }
            
        } catch (Exception e) {
            // 执行异常拦截器
            executeExceptionInterceptors(context, e);
            throw e;
        }
    }
    
    /**
     * 创建请求上下文
     */
    private DefaultRequestContext createRequestContext(Method method, Object[] args) {
        DefaultRequestContext context = new DefaultRequestContext();
        context.setMethod(method);
        context.setMethodArgs(args);
        context.setClient(httpClient);
        context.setStartTime(System.currentTimeMillis());
        return context;
    }
    
    /**
     * 执行拦截器链
     */
    private void executeInterceptors(DefaultRequestContext context, boolean preHandle) throws Exception {
        List<RequestInterceptor> allInterceptors = getAllInterceptors(context.getMethod());
        
        if (preHandle) {
            // 执行前置拦截器
            for (RequestInterceptor interceptor : allInterceptors) {
                interceptor.preHandle(context);
            }
        } else {
            // 执行后置拦截器(逆序)
            for (int i = allInterceptors.size() - 1; i >= 0; i--) {
                allInterceptors.get(i).postHandle(context);
            }
        }
    }
    
    /**
     * 执行异常拦截器
     */
    private void executeExceptionInterceptors(DefaultRequestContext context, Exception e) {
        List<RequestInterceptor> allInterceptors = getAllInterceptors(context.getMethod());
        
        for (RequestInterceptor interceptor : allInterceptors) {
            try {
                interceptor.afterThrowing(context, e);
            } catch (Exception ex) {
                // 忽略拦截器异常,避免掩盖原始异常
            }
        }
    }
    
    /**
     * 获取所有拦截器(全局 + 方法级)
     */
    private List<RequestInterceptor> getAllInterceptors(Method method) {
        List<RequestInterceptor> allInterceptors = new ArrayList<>(globalInterceptors);
        
        // 添加方法级拦截器
        if (method.isAnnotationPresent(MethodInterceptor.class)) {
            MethodInterceptor methodInterceptor = method.getAnnotation(MethodInterceptor.class);
            for (Class<? extends RequestInterceptor> interceptorClass : methodInterceptor.value()) {
                try {
                    allInterceptors.add(interceptorClass.newInstance());
                } catch (Exception e) {
                    throw new RuntimeException("Failed to create method interceptor: " + interceptorClass.getName(), e);
                }
            }
        }
        
        return allInterceptors;
    }
    
    /**
     * 构建HTTP请求
     */
    private HttpRequest buildHttpRequest(Method method, Object[] args) throws Exception {
        // 1. 获取HTTP方法
        HttpMethod httpMethod = getHttpMethod(method);
        if (httpMethod == null) {
            throw new IllegalArgumentException("Method must be annotated with HTTP method annotation");
        }
        
        // 2. 构建URL
        String url = buildUrl(method, args);
        
        // 3. 创建请求对象
        HttpRequest request = new HttpRequest();
        request.setMethod(httpMethod);
        request.setUrl(url);
        
        // 4. 处理参数
        processParameters(method, args, request);
        
        // 5. 处理方法级请求头
        processMethodHeaders(method, request);
        
        return request;
    }
    
    /**
     * 获取HTTP方法
     */
    private HttpMethod getHttpMethod(Method method) {
        if (method.isAnnotationPresent(GET.class)) {
            return HttpMethod.GET;
        } else if (method.isAnnotationPresent(POST.class)) {
            return HttpMethod.POST;
        } else if (method.isAnnotationPresent(PUT.class)) {
            return HttpMethod.PUT;
        } else if (method.isAnnotationPresent(DELETE.class)) {
            return HttpMethod.DELETE;
        }
        return null;
    }
    
    /**
     * 构建请求URL
     */
    private String buildUrl(Method method, Object[] args) {
        // 获取路径模板
        String pathTemplate = getPathTemplate(method);
        if (pathTemplate == null) {
            throw new IllegalArgumentException("No path template found for method: " + method.getName());
        }
        
        // 替换路径参数
        String path = replacePath Parameters(pathTemplate, method, args);
        
        // 添加查询参数
        String queryString = buildQueryString(method, args);
        if (!queryString.isEmpty()) {
            path += "?" + queryString;
        }
        
        return path;
    }
    
    /**
     * 获取路径模板
     */
    private String getPathTemplate(Method method) {
        if (method.isAnnotationPresent(GET.class)) {
            return method.getAnnotation(GET.class).value();
        } else if (method.isAnnotationPresent(POST.class)) {
            return method.getAnnotation(POST.class).value();
        } else if (method.isAnnotationPresent(PUT.class)) {
            return method.getAnnotation(PUT.class).value();
        } else if (method.isAnnotationPresent(DELETE.class)) {
            return method.getAnnotation(DELETE.class).value();
        }
        return null;
    }
    
    /**
     * 替换路径参数
     */
    private String replacePathParameters(String pathTemplate, Method method, Object[] args) {
        Map<String, Object> pathParams = getPathParameters(method, args);
        
        Matcher matcher = PATH_PARAM_PATTERN.matcher(pathTemplate);
        StringBuffer result = new StringBuffer();
        
        while (matcher.find()) {
            String paramName = matcher.group(1);
            Object paramValue = pathParams.get(paramName);
            
            if (paramValue == null) {
                throw new IllegalArgumentException("Path parameter '" + paramName + "' not found");
            }
            
            matcher.appendReplacement(result, String.valueOf(paramValue));
        }
        
        matcher.appendTail(result);
        return result.toString();
    }
    
    /**
     * 获取路径参数映射
     */
    private Map<String, Object> getPathParameters(Method method, Object[] args) {
        Map<String, Object> pathParams = new HashMap<>();
        Parameter[] parameters = method.getParameters();
        Annotation[][] parameterAnnotations = method.getParameterAnnotations();
        
        for (int i = 0; i < parameters.length; i++) {
            for (Annotation annotation : parameterAnnotations[i]) {
                if (annotation instanceof Path) {
                    Path pathAnnotation = (Path) annotation;
                    pathParams.put(pathAnnotation.value(), args[i]);
                    break;
                }
            }
        }
        
        return pathParams;
    }
    
    /**
     * 构建查询字符串
     */
    private String buildQueryString(Method method, Object[] args) {
        List<String> queryParts = new ArrayList<>();
        Parameter[] parameters = method.getParameters();
        Annotation[][] parameterAnnotations = method.getParameterAnnotations();
        
        for (int i = 0; i < parameters.length; i++) {
            for (Annotation annotation : parameterAnnotations[i]) {
                if (annotation instanceof Query) {
                    Query queryAnnotation = (Query) annotation;
                    Object value = args[i];
                    
                    if (value != null) {
                        String encodedValue = queryAnnotation.encoded() ? 
                            String.valueOf(value) : 
                            urlEncode(String.valueOf(value));
                        queryParts.add(queryAnnotation.value() + "=" + encodedValue);
                    }
                    break;
                }
            }
        }
        
        return String.join("&", queryParts);
    }
    
    /**
     * 处理方法参数
     */
    private void processParameters(Method method, Object[] args, HttpRequest request) throws Exception {
        Parameter[] parameters = method.getParameters();
        Annotation[][] parameterAnnotations = method.getParameterAnnotations();
        
        for (int i = 0; i < parameters.length; i++) {
            for (Annotation annotation : parameterAnnotations[i]) {
                if (annotation instanceof Body) {
                    // 设置请求体
                    Object body = args[i];
                    if (body != null) {
                        String jsonBody = objectMapper.writeValueAsString(body);
                        request.setBody(jsonBody);
                        // 设置Content-Type
                        request.getHeaders().put("Content-Type", "application/json");
                    }
                    break;
                } else if (annotation instanceof Header) {
                    // 设置动态请求头
                    Header headerAnnotation = (Header) annotation;
                    Object value = args[i];
                    if (value != null) {
                        request.getHeaders().put(headerAnnotation.value(), String.valueOf(value));
                    }
                    break;
                }
            }
        }
    }
    
    /**
     * 处理方法级请求头
     */
    private void processMethodHeaders(Method method, HttpRequest request) {
        if (method.isAnnotationPresent(Header.class)) {
            Header headerAnnotation = method.getAnnotation(Header.class);
            String headerValue = headerAnnotation.value();
            
            // 解析 "name: value" 格式的请求头
            if (headerValue.contains(":")) {
                String[] parts = headerValue.split(":", 2);
                String name = parts[0].trim();
                String value = parts[1].trim();
                request.getHeaders().put(name, value);
            }
        }
    }
    
    /**
     * 判断是否应该异步执行
     */
    private boolean shouldExecuteAsync(Method method) {
        // 1. 检查方法是否有@Async注解
        if (method.isAnnotationPresent(Async.class)) {
            return true;
        }
        
        // 2. 检查返回类型是否是CompletableFuture
        if (CompletableFuture.class.isAssignableFrom(method.getReturnType())) {
            return true;
        }
        
        // 3. 检查全局异步配置
        return defaultAsync;
    }
    
    /**
     * 同步执行
     */
    private Object executeSync(DefaultRequestContext context, Method method) throws Exception {
        // 创建响应处理器
        ResponseHandler<?> responseHandler = createResponseHandler(method);
        
        // 执行HTTP请求
        Object result = httpClient.execute(context.getRequest(), responseHandler);
        
        // 设置响应到上下文
        if (result instanceof Response) {
            context.setResponse((Response) result);
        }
        
        // 设置结束时间
        context.setEndTime(System.currentTimeMillis());
        
        // 执行后置拦截器
        executeInterceptors(context, false);
        
        return result;
    }
    
    /**
     * 异步执行
     */
    private CompletableFuture<?> executeAsync(DefaultRequestContext context, Method method) {
        // 获取执行器
        ExecutorService executor = getExecutor(method);
        
        return CompletableFuture.supplyAsync(() -> {
            try {
                return executeSync(context, method);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }, executor);
    }
    
    /**
     * 获取执行器
     */
    private ExecutorService getExecutor(Method method) {
        String executorName = null;
        
        // 优先使用方法级配置
        if (method.isAnnotationPresent(Async.class)) {
            executorName = method.getAnnotation(Async.class).executor();
        }
        
        // 其次使用全局配置
        if ((executorName == null || executorName.isEmpty()) && !defaultExecutorName.isEmpty()) {
            executorName = defaultExecutorName;
        }
        
        // TODO: 支持自定义执行器注册
        // 目前使用默认执行器
        return HttpClientFactory.getDefaultExecutor();
    }
    
    /**
     * 创建响应处理器
     */
    private ResponseHandler<?> createResponseHandler(Method method) {
        Class<?> returnType = method.getReturnType();
        
        // 处理CompletableFuture返回类型
        if (CompletableFuture.class.isAssignableFrom(returnType)) {
            Type genericReturnType = method.getGenericReturnType();
            if (genericReturnType instanceof ParameterizedType) {
                ParameterizedType parameterizedType = (ParameterizedType) genericReturnType;
                Type actualType = parameterizedType.getActualTypeArguments()[0];
                if (actualType instanceof Class) {
                    returnType = (Class<?>) actualType;
                }
            }
        }
        
        // 根据返回类型创建处理器
        if (returnType == void.class || returnType == Void.class) {
            return new VoidResponseHandler();
        } else {
            return new JsonResponseHandler<>(returnType, objectMapper);
        }
    }
    
    /**
     * 处理响应结果
     */
    private Object handleResponse(DefaultRequestContext context, Method method) {
        Response response = context.getResponse();
        if (response == null) {
            return null;
        }
        
        // 根据方法返回类型处理响应
        ResponseHandler<?> handler = createResponseHandler(method);
        try {
            return handler.handle(response);
        } catch (Exception e) {
            throw new RuntimeException("Failed to handle response", e);
        }
    }
    
    /**
     * URL编码
     */
    private String urlEncode(String value) {
        try {
            return java.net.URLEncoder.encode(value, "UTF-8");
        } catch (Exception e) {
            return value;
        }
    }
}

请求上下文实现

为了在拦截器之间传递信息,我们需要实现请求上下文:

java 复制代码
package io.github.nemoob.httpclient;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

/**
 * 默认请求上下文实现
 */
public class DefaultRequestContext implements RequestContext {
    
    private Request request;
    private Response response;
    private Method method;
    private Object[] methodArgs;
    private HttpClient client;
    private final Map<String, Object> attributes = new HashMap<>();
    private long startTime;
    private long endTime;
    
    @Override
    public Request getRequest() {
        return request;
    }
    
    @Override
    public void setRequest(Request request) {
        this.request = request;
    }
    
    @Override
    public Response getResponse() {
        return response;
    }
    
    @Override
    public void setResponse(Response response) {
        this.response = response;
    }
    
    @Override
    public Method getMethod() {
        return method;
    }
    
    @Override
    public void setMethod(Method method) {
        this.method = method;
    }
    
    @Override
    public Object[] getMethodArgs() {
        return methodArgs;
    }
    
    @Override
    public void setMethodArgs(Object[] methodArgs) {
        this.methodArgs = methodArgs;
    }
    
    @Override
    public HttpClient getClient() {
        return client;
    }
    
    @Override
    public void setClient(HttpClient client) {
        this.client = client;
    }
    
    @Override
    public void setAttribute(String name, Object value) {
        attributes.put(name, value);
    }
    
    @Override
    public Object getAttribute(String name) {
        return attributes.get(name);
    }
    
    @Override
    public long getStartTime() {
        return startTime;
    }
    
    public void setStartTime(long startTime) {
        this.startTime = startTime;
    }
    
    @Override
    public long getEndTime() {
        return endTime;
    }
    
    @Override
    public void setEndTime(long endTime) {
        this.endTime = endTime;
    }
}

完整的调用流程

让我们通过一个完整的示例来理解整个调用流程:

java 复制代码
// 1. 定义接口
@HttpClient("https://api.example.com")
public interface UserService {
    @GET("/users/{id}")
    User getUser(@Path("id") Long id);
}

// 2. 创建客户端
UserService userService = HttpClientFactory.create(UserService.class);

// 3. 调用方法
User user = userService.getUser(123L);

调用流程:

markdown 复制代码
1. userService.getUser(123L)
   ↓
2. 动态代理拦截调用
   ↓
3. HttpClientInvocationHandler.invoke()
   ↓
4. 创建请求上下文
   ↓
5. 执行前置拦截器
   ↓
6. 解析@GET("/users/{id}")注解
   ↓
7. 解析@Path("id")参数
   ↓
8. 构建HTTP请求:GET /users/123
   ↓
9. 调用SimpleHttpClient.execute()
   ↓
10. 发送HTTP请求
   ↓
11. 接收HTTP响应
   ↓
12. 使用JsonResponseHandler转换响应
   ↓
13. 执行后置拦截器
   ↓
14. 返回User对象

异步处理机制

框架支持两种异步处理方式:

1. 方法级异步

java 复制代码
@HttpClient("https://api.example.com")
public interface UserService {
    @GET("/users")
    @Async
    CompletableFuture<List<User>> getUsersAsync();
}

2. 全局异步

java 复制代码
@HttpClient(value = "https://api.example.com", async = true)
public interface UserService {
    @GET("/users")
    CompletableFuture<List<User>> getUsers();
}

异步执行的关键代码:

java 复制代码
private CompletableFuture<?> executeAsync(DefaultRequestContext context, Method method) {
    ExecutorService executor = getExecutor(method);
    
    return CompletableFuture.supplyAsync(() -> {
        try {
            return executeSync(context, method);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }, executor);
}

错误处理机制

框架提供了完善的错误处理机制:

1. 参数验证

java 复制代码
// 验证接口定义
if (!clientClass.isInterface()) {
    throw new IllegalArgumentException("Only interfaces are supported");
}

// 验证注解
if (!clientClass.isAnnotationPresent(HttpClient.class)) {
    throw new IllegalArgumentException("Interface must be annotated with @HttpClient");
}

2. 运行时异常处理

java 复制代码
try {
    // 执行HTTP请求
    Object result = httpClient.execute(context.getRequest(), responseHandler);
    return result;
} catch (Exception e) {
    // 执行异常拦截器
    executeExceptionInterceptors(context, e);
    throw e;
}

3. 拦截器异常隔离

java 复制代码
private void executeExceptionInterceptors(DefaultRequestContext context, Exception e) {
    for (RequestInterceptor interceptor : allInterceptors) {
        try {
            interceptor.afterThrowing(context, e);
        } catch (Exception ex) {
            // 忽略拦截器异常,避免掩盖原始异常
        }
    }
}

性能优化考虑

1. 反射缓存

java 复制代码
// 可以考虑缓存方法信息
private static final Map<Method, MethodInfo> METHOD_CACHE = new ConcurrentHashMap<>();

public MethodInfo getMethodInfo(Method method) {
    return METHOD_CACHE.computeIfAbsent(method, this::parseMethod);
}

2. 对象池

java 复制代码
// 可以考虑使用对象池来减少对象创建
private static final ObjectPool<HttpRequest> REQUEST_POOL = new ObjectPool<>(HttpRequest::new);

3. 异步执行器管理

java 复制代码
// 合理配置线程池
private static final ExecutorService defaultExecutor = Executors.newCachedThreadPool(
    new ThreadFactoryBuilder()
        .setNameFormat("atlas-http-client-%d")
        .setDaemon(true)
        .build()
);

总结

本文详细介绍了 Atlas HTTP Client 框架的动态代理与请求处理机制。关键要点包括:

  1. 动态代理核心:使用 JDK 动态代理拦截方法调用
  2. 注解解析:运行时解析方法和参数注解
  3. 请求构建:根据注解信息构建 HTTP 请求
  4. 拦截器链:支持前置、后置和异常拦截器
  5. 异步支持:基于 CompletableFuture 的异步执行
  6. 错误处理:完善的异常处理和验证机制

动态代理机制是整个框架的核心,它将用户的声明式接口转换为实际的 HTTP 请求。通过精心设计的处理流程,我们实现了一个功能强大、易于使用的 HTTP 客户端框架。

相关推荐
Flittly17 小时前
【AgentScope Java新手村系列】(16)从RAG到多路检索
java·spring boot·spring
小兔崽子去哪了17 小时前
Java 生成二维码解决方案
java·后端
YuePeng19 小时前
写了五年注解的低代码框架,2.0 决定让你连注解都不用写了
github·产品
小白ai19 小时前
从"能 ping 通吗"到"为什么上不了网"——我写了一个网络故障诊断引擎
github
徐小夕21 小时前
jitword 协同文档3.2发布:打造浏览器中最强word编辑器
前端·架构·github
人活一口气1 天前
从JVM调优到MCP协议:Java全栈技术体系深度总结与企业级架构实践
java·spring boot
齐翊1 天前
分享一个在 Claude Code 里 [同时] 用多个 ApiKey 的方法
程序员·github·agent
A_Lonely_Cat1 天前
记一次 GitHub 幽灵协作者大清洗:强制重写 Git 历史与穿透 CDN 缓存实践
git·github
NE_STOP1 天前
Vibe Coding -- 完整项目案例实操
java
荣码1 天前
GraphRAG:普通RAG只能回答"点"的问题,我踩了4个坑才搞懂
java·python