Field Query POST GET注解
@Target(PARAMETER)
@Retention(RUNTIME)
public @interface Field {
String value();
}
@Target(PARAMETER)
@Retention(RUNTIME)
public @interface Query {
String value();
}
@Target(METHOD)
@Retention(RUNTIME)
public @interface POST {
String value() default "";
}
@Target(METHOD)
@Retention(RUNTIME)
public @interface GET {
String value() default "";
}
retrofit动态代理解析注解
public class EnjoyRetrofit {
final Map<Method, ServiceMethod> serviceMethodCache = new ConcurrentHashMap<>();
final Call.Factory callFactory;
final HttpUrl baseUrl;
EnjoyRetrofit(Call.Factory callFactory, HttpUrl baseUrl) {
this.callFactory = callFactory;
this.baseUrl = baseUrl;
}
public <T> T create(final Class<T> service) {
return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class[]{service},
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//解析这个method 上所有的注解信息
ServiceMethod serviceMethod = loadServiceMethod(method);
//args:
return serviceMethod.invoke(args);
}
});
}
private ServiceMethod loadServiceMethod(Method method) {
//先不上锁,避免synchronized的性能损失
ServiceMethod result = serviceMethodCache.get(method);
if (result != null) return result;
//多线程下,避免重复解析,
synchronized (serviceMethodCache) {
result = serviceMethodCache.get(method);
if (result == null) {
result = new ServiceMethod.Builder(this, method).build();
serviceMethodCache.put(method, result);
}
}
return result;
}
/**
* 构建者模式,将一个复杂对象的构建和它的表示分离,可以使使用者不必知道内部组成的细节。
*/
public static final class Builder {
private HttpUrl baseUrl;
//Okhttp->OkhttClient
private okhttp3.Call.Factory callFactory; //null
public Builder callFactory(okhttp3.Call.Factory factory) {
this.callFactory = factory;
return this;
}
public Builder baseUrl(String baseUrl) {
this.baseUrl = HttpUrl.get(baseUrl);
return this;
}
public EnjoyRetrofit build() {
if (baseUrl == null) {
throw new IllegalStateException("Base URL required.");
}
okhttp3.Call.Factory callFactory = this.callFactory;
if (callFactory == null) {
callFactory = new OkHttpClient();
}
return new EnjoyRetrofit(callFactory, baseUrl);
}
}
}
参数的获取
public abstract class ParameterHandler {
abstract void apply(ServiceMethod serviceMethod, String value);
static class QueryParameterHandler extends ParameterHandler {
String key;
public QueryParameterHandler(String key) {
this.key = key;
}
//serviceMethod: 回调
@Override
void apply(ServiceMethod serviceMethod, String value) {
serviceMethod.addQueryParameter(key,value);
}
}
static class FiledParameterHandler extends ParameterHandler {
String key;
public FiledParameterHandler(String key) {
this.key = key;
}
@Override
void apply(ServiceMethod serviceMethod, String value) {
serviceMethod.addFiledParameter(key,value);
}
}
}
GET和POST请求处理
public class ServiceMethod {
private final Call.Factory callFactory;
private final String relativeUrl;
private final boolean hasBody;
private final ParameterHandler[] parameterHandler;
private FormBody.Builder formBuild;
HttpUrl baseUrl;
String httpMethod;
HttpUrl.Builder urlBuilder;
public ServiceMethod(Builder builder) {
baseUrl = builder.enjoyRetrofit.baseUrl;
callFactory = builder.enjoyRetrofit.callFactory;
httpMethod = builder.httpMethod;
relativeUrl = builder.relativeUrl;
hasBody = builder.hasBody;
parameterHandler = builder.parameterHandler;
//如果是有请求体,创建一个okhttp的请求体对象
if (hasBody) {
formBuild = new FormBody.Builder();
}
}
public Object invoke(Object[] args) {
/**
* 1 处理请求的地址与参数
*/
for (int i = 0; i < parameterHandler.length; i++) {
ParameterHandler handlers = parameterHandler[i];
//handler内本来就记录了key,现在给到对应的value
handlers.apply(this, args[i].toString());
}
//获取最终请求地址
HttpUrl url;
if (urlBuilder == null) {
urlBuilder = baseUrl.newBuilder(relativeUrl);
}
url = urlBuilder.build();
//请求体
FormBody formBody = null;
if (formBuild != null) {
formBody = formBuild.build();
}
Request request = new Request.Builder().url(url).method(httpMethod, formBody).build();
return callFactory.newCall(request);
}
// get请求, 把 k-v 拼到url里面
public void addQueryParameter(String key, String value) {
if (urlBuilder == null) {
urlBuilder = baseUrl.newBuilder(relativeUrl);
}
urlBuilder.addQueryParameter(key, value);
}
//Post 把k-v 放到 请求体中
public void addFiledParameter(String key, String value) {
formBuild.add(key, value);
}
public static class Builder {
private final EnjoyRetrofit enjoyRetrofit;
private final Annotation[] methodAnnotations;
private final Annotation[][] parameterAnnotations;
ParameterHandler[] parameterHandler;
private String httpMethod;
private String relativeUrl;
private boolean hasBody;
public Builder(EnjoyRetrofit enjoyRetrofit, Method method) {
this.enjoyRetrofit = enjoyRetrofit;
//获取方法上的所有的注解
methodAnnotations = method.getAnnotations();
//获得方法参数的所有的注解 (一个参数可以有多个注解,一个方法又会有多个参数)
parameterAnnotations = method.getParameterAnnotations();
}
public ServiceMethod build() {
/**
* 1 解析方法上的注解, 只处理POST与GET
*/
for (Annotation methodAnnotation : methodAnnotations) {
if (methodAnnotation instanceof POST) {
//记录当前请求方式
this.httpMethod = "POST";
//记录请求url的path
this.relativeUrl = ((POST) methodAnnotation).value();
// 是否有请求体
this.hasBody = true;
} else if (methodAnnotation instanceof GET) {
this.httpMethod = "GET";
this.relativeUrl = ((GET) methodAnnotation).value();
this.hasBody = false;
}
}
/**
* 2 解析方法参数的注解
*/
int length = parameterAnnotations.length;
parameterHandler = new ParameterHandler[length];
for (int i = 0; i < length; i++) {
// 一个参数上的所有的注解
Annotation[] annotations = parameterAnnotations[i];
// 处理参数上的每一个注解
for (Annotation annotation : annotations) {
//todo 可以加一个判断:如果httpMethod是get请求,现在又解析到Filed注解,可以提示使用者使用Query注解
if (annotation instanceof Field) {
//得到注解上的value: 请求参数的key
String value = ((Field) annotation).value();
parameterHandler[i] = new ParameterHandler.FiledParameterHandler(value);
} else if (annotation instanceof Query) {
String value = ((Query) annotation).value();
parameterHandler[i] = new ParameterHandler.QueryParameterHandler(value);
}
}
}
return new ServiceMethod(this);
}
}
}
