项目整体结构
自定义WeatherApi类
package com.example.lsn_compose.BarryLRetrofit.api;
import com.example.lsn_compose.BarryLRetrofit.retrofit.annotation.Field;
import com.example.lsn_compose.BarryLRetrofit.retrofit.annotation.GET;
import com.example.lsn_compose.BarryLRetrofit.retrofit.annotation.POST;
import com.example.lsn_compose.BarryLRetrofit.retrofit.annotation.Query;
import okhttp3.Call;
import retrofit2.http.FormUrlEncoded;
public interface BarryLWeatherApi {
@POST("/v3/weather/weatherInfo")
@FormUrlEncoded
Call postWeather(@Field("city") String city, @Field("key") String key);
@GET("/v3/weather/weatherInfo")
Call getWeather(@Query("city") String city, @Query("key") String key);
}
注解部分
@Target(PARAMETER)//参数注解
@Retention(RUNTIME)//运行时注解,只有用运行时注解才能反射获取
public @interface Field {
String value();
}
package com.example.lsn_compose.BarryLRetrofit.retrofit.annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
@Target(METHOD)
@Retention(RUNTIME)
public @interface GET {
String value() default "";
}
package com.example.lsn_compose.BarryLRetrofit.retrofit.annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
@Target(METHOD)
@Retention(RUNTIME)
public @interface POST {
String value() default "";
}
package com.example.lsn_compose.BarryLRetrofit.retrofit.annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.PARAMETER;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
@Target(PARAMETER)
@Retention(RUNTIME)
public @interface Query {
String value();
}
自定义Retrofit类
package com.example.lsn_compose.BarryLRetrofit.retrofit;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import okhttp3.Call;
import okhttp3.HttpUrl;
import okhttp3.OkHttpClient;
/**
* @author BoyuanLiu
* @date 2021年04月27日 12:19
*/
public class BarryLRetrofit {
final Map<Method, ServiceMethod> serviceMethodCache = new ConcurrentHashMap<>();
final Call.Factory callFactory;
final HttpUrl baseUrl;
BarryLRetrofit(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 o, Method method, Object[] objects) throws Throwable {
//解析这个method上所有的注解信息
ServiceMethod serviceMethod = loadServiceMethod(method);
//反射
return serviceMethod.invoke(objects);
}
});
}
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;
private okhttp3.Call.Factory callFactory;
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 BarryLRetrofit build() {
if (baseUrl == null) {
throw new IllegalStateException("Base URL required.");
}
okhttp3.Call.Factory callFactory = this.callFactory;
if (callFactory == null) {
callFactory = new OkHttpClient();
}
return new BarryLRetrofit(callFactory, baseUrl);
}
}
}
参数传递类,一个用于拼接注解上得到的key-value的handler,是一个抽象类
package com.example.lsn_compose.BarryLRetrofit.retrofit;
/**
* @author BoyuanLiu
* @date 2021年04月27日 12:19
*/
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;
}
@Override
void apply(ServiceMethod serviceMethod, String value) {
serviceMethod.addQueryParameter(key, value);
}
}
static class FieldParameterHandler extends ParameterHandler {
String key;
public FieldParameterHandler(String key) {
this.key = key;
}
@Override
void apply(ServiceMethod serviceMethod, String value) {
serviceMethod.addFiledParameter(key, value);
}
}
}
ServiceMethod类
package com.example.lsn_compose.BarryLRetrofit.retrofit;
import com.example.lsn_compose.BarryLRetrofit.retrofit.annotation.Field;
import com.example.lsn_compose.BarryLRetrofit.retrofit.annotation.GET;
import com.example.lsn_compose.BarryLRetrofit.retrofit.annotation.POST;
import com.example.lsn_compose.BarryLRetrofit.retrofit.annotation.Query;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import okhttp3.Call;
import okhttp3.FormBody;
import okhttp3.HttpUrl;
import okhttp3.Request;
/**
* @author BoyuanLiu
* @date 2021年04月27日 12:20
*/
public class ServiceMethod {
//网络请求工厂 即okhttp的网络请求
private final Call.Factory callFactory;
//网络请求的相对地址 和baseUrl拼接起来就是实际地址
private final String relativeUrl;
private final boolean hasBody;
//方法参数的处理器 比如我们定义的方法,get方法和后面的参数"city"、"key"
private final ParameterHandler[] parameterHandler;
//表单提交方式的表单体
private FormBody.Builder formBuild;
//网络基地址
HttpUrl baseUrl;
//网络请求的http方法 POST GET
String httpMethod;
HttpUrl.Builder urlBuilder;
public ServiceMethod(Builder builder) {
baseUrl = builder.barryLRetrofit.baseUrl;
callFactory = builder.barryLRetrofit.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);
}
//Post 把k-v 放到 请求体中
public void addFiledParameter(String key, String value) {
formBuild.add(key, value);
}
// get请求, 把 k-v 拼到url里面
public void addQueryParameter(String key, String value) {
if (urlBuilder == null) {
urlBuilder = baseUrl.newBuilder(relativeUrl);
}
urlBuilder.addQueryParameter(key, value);
}
public static class Builder {
private final BarryLRetrofit barryLRetrofit;
private final Annotation[] methodAnnotations;
private final Annotation[][] parameterAnnotations;
ParameterHandler[] parameterHandler;
private String httpMethod;
private String relativeUrl;
private boolean hasBody;
public Builder(BarryLRetrofit barryLRetrofit, Method method) {
this.barryLRetrofit = barryLRetrofit;
//获取方法上的所有的注解
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) {
if (annotation instanceof Field) {
//得到注解上的value: 请求参数的key
String value = ((Field) annotation).value();
parameterHandler[i] = new ParameterHandler.FieldParameterHandler(value);
} else if (annotation instanceof Query) {
String value = ((Query) annotation).value();
parameterHandler[i] = new ParameterHandler.QueryParameterHandler(value);
}
}
}
return new ServiceMethod(this);
}
}
}
调用
BarryLRetrofit barryLRetrofit = new BarryLRetrofit.Builder().baseUrl("https://restapi.amap.com").build();
barryLWeatherApi = barryLRetrofit.create(BarryLWeatherApi.class);
barryGet();
barryPost();
public void barryGet() {
Call call = barryLWeatherApi.getWeather("110101", "ae6c53e2186f33bbf240a12d80672d1b");
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
Log.i(tag, "GET" + response.body().string());
response.close();
}
});
}
public void barryPost() {
Call call = barryLWeatherApi.postWeather("110101", "ae6c53e2186f33bbf240a12d80672d1b");
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
Log.i(tag, "POST" + response.body().string());
response.close();
}
});
}