手把手教你写 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 客户端框架。

相关推荐
华仔啊19 小时前
王者段位排行榜如何实现?Redis有序集合实战
java·redis·后端
TeamDev1 天前
用一个 prompt 搭建带 React 界面的 Java 桌面应用
java·前端·后端
知其然亦知其所以然1 天前
国产大模型也能无缝接入!Spring AI + 智谱 AI 实战指南
java·后端·算法
用户90555842148051 天前
spymemcached重要组成部分-IO源码解析
java
吟风于春1 天前
Spring 中 REQUIRED 事务的回滚机制详解
java
阿杆1 天前
国产神级开源 OCR 模型,GitHub 55k Star!再次起飞!
后端·github·图像识别
RainbowSea1 天前
14. Java开发者LLM实战——LangChain4j最新知识库实战
java·langchain·ai编程
RainbowSea1 天前
13. LangChain4j + 加入检索增加生成 RAG(知识库)
java·langchain·ai编程
杨杨杨大侠1 天前
Atlas Mapper 案例 03:企业级订单实体设计文档
java·开源·github