前言
在前两篇文章中,我们分别介绍了框架的整体架构设计和核心注解系统。从本篇开始,我们将深入到框架的核心实现 ------ 动态代理机制。
动态代理是整个框架的心脏,它负责:
- 拦截用户的方法调用
- 解析方法上的注解信息
- 构建 HTTP 请求
- 执行拦截器链
- 调用底层 HTTP 客户端
- 处理响应结果
理解动态代理机制对于掌握框架的工作原理至关重要。
动态代理基础知识
什么是动态代理?
动态代理是 Java 反射机制的一个重要应用,它允许我们在运行时创建一个实现了指定接口的代理对象。当调用代理对象的方法时,会被转发到 InvocationHandler
的 invoke
方法中处理。
为什么选择动态代理?
- 无需实现类:用户只需定义接口,框架自动生成实现
- 统一处理:所有方法调用都会经过同一个处理器
- 灵活性强:可以根据方法信息动态决定处理逻辑
- 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 框架的动态代理与请求处理机制。关键要点包括:
- 动态代理核心:使用 JDK 动态代理拦截方法调用
- 注解解析:运行时解析方法和参数注解
- 请求构建:根据注解信息构建 HTTP 请求
- 拦截器链:支持前置、后置和异常拦截器
- 异步支持:基于 CompletableFuture 的异步执行
- 错误处理:完善的异常处理和验证机制
动态代理机制是整个框架的核心,它将用户的声明式接口转换为实际的 HTTP 请求。通过精心设计的处理流程,我们实现了一个功能强大、易于使用的 HTTP 客户端框架。