本文主要介紹Retrofit用到的設(shè)計(jì)模式,包括代理模式,工廠方法模式,抽象工廠模式,適配器模式,建造者模式,策略模式。
1、Retrofit基本使用
1.1、定義Service
interface Service {
@Headers(
"Cache-Control: max-age=640000, max-stale=864000",
"Authorization: APPCODE " + APP_CODE,
)
@GET("/{path}")
fun getDate(
@Path("path") path: String,
@QueryMap() map: MutableMap<String, String>
): Observable<Any>
}
1.2、創(chuàng)建代理對(duì)象,執(zhí)行請(qǐng)求
val executorService = Executors.newCachedThreadPool();
var okHttpClient = OkHttpClient.Builder().dispatcher(Dispatcher(executorService))
.addInterceptor label@{
Log.d(TAG, "getNetWork1: 數(shù)據(jù)請(qǐng)求發(fā)起線程 " + Thread.currentThread().name)
return@label it.proceed(it.request())
}
.addNetworkInterceptor(object : Interceptor {
override fun intercept(chain: Interceptor.Chain): Response {
Log.d(TAG, "intercept: ------進(jìn)行了網(wǎng)絡(luò)請(qǐng)求" + Thread.currentThread().name)
var request = chain.request()
Log.d(TAG, "intercept: " + request.toString())
return chain.proceed(request)
}
}).cache(Cache(file, 10 * 1024 * 1024))
.build()
var retrofit = Retrofit.Builder().baseUrl(RetrofitActivity.BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.client(okHttpClient)
//異步結(jié)果返回的線程。就是enqueue的caback所在線程,默認(rèn)主線程。
.callbackExecutor(Executors.newCachedThreadPool())
.build()
// retrofit.callFactory().newCall()
var service = retrofit.create(Service::class.java)
service.getDate4(
path = "area-to-weather-date",
map = mutableMapOf<String, String>(
"area" to "麗江",
"areaCode" to "530700",
"date" to "20200319",
"need3HourForcast" to "1"
)
).observeOn(Schedulers.newThread()).subscribe {
Log.d(TAG, "onResponse: exec數(shù)據(jù)返回線程 " + Thread.currentThread().name + " ")
tvContent?.setText("" + it.toString())
}
2、Retrofit調(diào)用流程

??創(chuàng)建Service代理對(duì)象,調(diào)用Service中的方法,解析注解,構(gòu)建RequestFactroy,這個(gè)用于創(chuàng)建request,解析注解包括解析方法注解,解析使用的請(qǐng)求方式,GET、POST請(qǐng)求,解析參數(shù)注解,傳參如FieldMap注解,通過傳入的CalladapterFactroy拿到CallAdapter,通過傳入的ConvertFactroy拿到Convert,返回HttpServiceMethod的子類CallAdapted<>。
??invoke創(chuàng)建OKhttpCall,執(zhí)行同步和異步請(qǐng)求,使用上面解析完成的RequestFactroy創(chuàng)建Request,創(chuàng)建okhttp的call,執(zhí)行請(qǐng)求,返回ResponseBody,body再通過轉(zhuǎn)化為Response<JavaBean>,再通過callBack回調(diào)給RxJavaCalladapter處理成Observable對(duì)象,最終用Object接收,返回給動(dòng)態(tài)代理中作為方法的返回值。
2.1、創(chuàng)建代理對(duì)象,解析注解。
// Retrofit
public <T> T create(final Class<T> service) {
validateServiceInterface(service);
return (T)
Proxy.newProxyInstance(
service.getClassLoader(),
new Class<?>[] {service},
new InvocationHandler() {
private final Platform platform = Platform.get();
private final Object[] emptyArgs = new Object[0];
@Override
public @Nullable Object invoke(Object proxy, Method method, @Nullable Object[] args)
throws Throwable {
args = args != null ? args : emptyArgs;
return platform.isDefaultMethod(method)
? platform.invokeDefaultMethod(method, service, proxy, args)
: loadServiceMethod(method).invoke(args);
}
});
}
2.2、創(chuàng)建OkhttpCall
// HttpServiceMethod
@Override
final @Nullable ReturnT invoke(Object[] args) {
Call<ResponseT> call = new OkHttpCall<>(requestFactory, args, callFactory, responseConverter);
return adapt(call, args);
}
2.3、以RxJava2CallAdapter為例,執(zhí)行請(qǐng)求
final class RxJava2CallAdapter<R> implements CallAdapter<R, Object> {
@Override public Type responseType() {
return responseType;
}
@Override public Object adapt(Call<R> call) {
Observable<Response<R>> responseObservable = isAsync
? new CallEnqueueObservable<>(call)
: new CallExecuteObservable<>(call);
return observable;
}
}
final class CallEnqueueObservable<T> extends Observable<Response<T>> {
private final Call<T> originalCall;
CallEnqueueObservable(Call<T> originalCall) {
this.originalCall = originalCall;
}
@Override protected void subscribeActual(Observer<? super Response<T>> observer) {
Call<T> call = originalCall.clone();
CallCallback<T> callback = new CallCallback<>(call, observer);
observer.onSubscribe(callback);
call.enqueue(callback);
}
}
這里的Call是OKHttpCall,調(diào)用enqueue,執(zhí)行真正的call請(qǐng)求,返回結(jié)果給CallEnqueueObservable 的callback,調(diào)用 observer.onNext(response)向下傳遞,包裝成了Observable對(duì)象。
2.4、執(zhí)行真正的請(qǐng)求
//OkHttp
public void enqueue(final Callback<T> callback) {
synchronized (this) {
try {
call = rawCall = createRawCall();
}
}
call.enqueue(
new okhttp3.Callback() {
@Override
public void onResponse(okhttp3.Call call, okhttp3.Response rawResponse) {
Response<T> response;
try {
response = parseResponse(rawResponse);
}
try {
callback.onResponse(OkHttpCall.this, response);
}
}
});
}
private okhttp3.Call createRawCall() throws IOException {
okhttp3.Call call = callFactory.newCall(requestFactory.create(args));
return call;
}
requestFactory.create(args)構(gòu)建request,將方法參數(shù)解析的結(jié)果添加到request里面。
2.5、返回ResponseBody轉(zhuǎn)化成Response<DataBean>
// OkHttpCall
Response<T> parseResponse(okhttp3.Response rawResponse) throws IOException {
ResponseBody rawBody = rawResponse.body();
rawResponse =
rawResponse
.newBuilder()
.body(new OkHttpCall.NoContentResponseBody(rawBody.contentType(), rawBody.contentLength()))
.build();
int code = rawResponse.code();
ExceptionCatchingResponseBody catchingBody = new ExceptionCatchingResponseBody(rawBody);
try {
T body = responseConverter.convert(catchingBody);
return Response.success(body, rawResponse);
}
}
3、動(dòng)態(tài)代理模式
??執(zhí)行Service方法使用了代理模式。
??好處1、 比如使用某個(gè)網(wǎng)絡(luò)框架請(qǐng)求數(shù)據(jù),后來換成其他網(wǎng)絡(luò)請(qǐng)求框架,如果不使用代理模式,需要將使用的地方刪除,可能很多。使用代理,只會(huì)改掉代理里面的就可以了。
??好處2、如果被代理者3個(gè)方法,被代理者只授權(quán)使用2個(gè),那么就可以使用代理模式了,避免客戶直接訪問被代理者的受限方法。

public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)
4、建造者模式
??創(chuàng)建Retrofit、RequestFactroy使用了建造者模式。
??好處: 將對(duì)象的實(shí)現(xiàn)細(xì)節(jié),封裝在內(nèi)部,高內(nèi)聚。相同的構(gòu)建過程,可以創(chuàng)建不同的產(chǎn)品。

// RequestFactory
RequestFactory(Builder builder) {
method = builder.method;
baseUrl = builder.retrofit.baseUrl;
httpMethod = builder.httpMethod;
relativeUrl = builder.relativeUrl;
headers = builder.headers;
contentType = builder.contentType;
hasBody = builder.hasBody;
parameterHandlers = builder.parameterHandlers;
}
//Builder
RequestFactory build() {
for (Annotation annotation : methodAnnotations) {
parseMethodAnnotation(annotation);
}
int parameterCount = parameterAnnotationsArray.length;
parameterHandlers = new ParameterHandler<?>[parameterCount];
for (int p = 0, lastParameter = parameterCount - 1; p < parameterCount; p++) {
parameterHandlers[p] =
parseParameter(p, parameterTypes[p], parameterAnnotationsArray[p], p == lastParameter);
}
return new RequestFactory(this);
}
5、工廠模式
1.1、創(chuàng)建CallAdapter使用了工廠方法模式
?? 相比較簡單工廠,簡單工廠再創(chuàng)建adapter,需要修改factroy類,所以一般框架都是使用工廠方法和抽象工廠,避免修改,對(duì)修改關(guān)閉,對(duì)擴(kuò)展開放。

abstract class Factory {
public abstract @Nullable CallAdapter<?, ?> get(
Type returnType, Annotation[] annotations, Retrofit retrofit);
}
public final class RxJava2CallAdapterFactory extends CallAdapter.Factory {
public CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
return new RxJava2CallAdapter(responseType, scheduler, isAsync, isResult, isBody, isFlowable,
isSingle, isMaybe, false);
}
}
final class RxJava2CallAdapter<R> implements CallAdapter<R, Object> {
@Override public Object adapt(Call<R> call) {
}
}
??每一個(gè)CallAdapter的子類型Adapter對(duì)應(yīng)一個(gè)Factroy的子類型工廠。 CallAdapter主要負(fù)責(zé)在adapt方法中請(qǐng)求數(shù)據(jù),配置Retrofit時(shí),傳遞的不同F(xiàn)actroy,決定了不同的Adpter。
1.2、創(chuàng)建Converter對(duì)象使用了抽象工廠模式
?? Factory創(chuàng)建同一類的多個(gè)相類似的產(chǎn)品,也避免了在Factory中修改。

public final class GsonConverterFactory extends Converter.Factory {
@Override
public Converter<ResponseBody, ?> responseBodyConverter(
Type type, Annotation[] annotations, Retrofit retrofit) {
TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));
return new GsonResponseBodyConverter<>(gson, adapter);
}
@Override
public Converter<?, RequestBody> requestBodyConverter(
Type type) {
TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));
return new GsonRequestBodyConverter<>(gson, adapter);
}
}
final class GsonResponseBodyConverter<T> implements Converter<ResponseBody, T> {
private final TypeAdapter<T> adapter;
@Override
public T convert(ResponseBody value) throws IOException {
JsonReader jsonReader = gson.newJsonReader(value.charStream());
try {
T result = adapter.read(jsonReader);
return result;
}
}
}
??可以看到每個(gè)工廠可以創(chuàng)建2個(gè)Converter,以GsonConverterFactory為例,一個(gè)工廠創(chuàng)建了GsonRequestBodyConverter和GsonResponseBodyConverter對(duì)象。GsonRequestBodyConverter負(fù)責(zé)將ResponseBody通過Gson轉(zhuǎn)化成ResponType類型。GsonRequestBodyConverter將傳入的java對(duì)象寫入到RequestBody中。
6、適配器模式
??將某個(gè)類的接口轉(zhuǎn)化為客戶端期望的另一個(gè)接口表示,主要的目的是兼容性,讓原本不匹配不能一起工作的兩個(gè)類可以協(xié)同工作。

// 創(chuàng)建
new CallAdapted<>(requestFactory, callFactory, responseConverter, callAdapter);
static final class CallAdapted<ResponseT, ReturnT> extends HttpServiceMethod<ResponseT, ReturnT> {
private final CallAdapter<ResponseT, ReturnT> callAdapter;
@Override
protected ReturnT adapt(Call<ResponseT> call, Object[] args) {
return callAdapter.adapt(call);
}
}
final class RxJava2CallAdapter<R> implements CallAdapter<R, Object> {
@Override public Type responseType() {
return responseType;
}
@Override public Object adapt(Call<R> call) {
Observable<Response<R>> responseObservable = isAsync
? new CallEnqueueObservable<>(call)
: new CallExecuteObservable<>(call);
return observable;
}
}
final class CallEnqueueObservable<T> extends Observable<Response<T>> {
private final Call<T> originalCall;
@Override protected void subscribeActual(Observer<? super Response<T>> observer) {
Call<T> call = originalCall.clone();
CallCallback<T> callback = new CallCallback<>(call, observer);
observer.onSubscribe(callback);
call.enqueue(callback);
}
private static final class CallCallback<T> implements Disposable, Callback<T> {
CallCallback(Call<?> call, Observer<? super Response<T>> observer) {
this.call = call;
this.observer = observer;
}
@Override public void onResponse(Call<T> call, Response<T> response) {
try {
observer.onNext(response);
}
}
}
}
??HttpServiceMethod類通過CallFactroy、responseConverter、callAdapter創(chuàng)建OkhttpCall對(duì)象,并且抽象了adapt方法,這個(gè)方法負(fù)責(zé)請(qǐng)求數(shù)據(jù)。
?? 子類CallAdapted 實(shí)現(xiàn)adapt方法,執(zhí)行Call請(qǐng)求,但是該方法的具體實(shí)現(xiàn)在CallAdapter中的adapt中實(shí)現(xiàn)的。
?? 比如上述的CallAdapter為RxJava2CallAdapter時(shí),執(zhí)行Call請(qǐng)求在RxJava2CallAdapter的adapt方法中,執(zhí)行adapt方法返回了Observable<Response<R>>類型。

final class GsonResponseBodyConverter<T> implements Converter<ResponseBody, T> {
private final TypeAdapter<T> adapter;
@Override
public T convert(ResponseBody value) throws IOException {
JsonReader jsonReader = gson.newJsonReader(value.charStream());
try {
T result = adapter.read(jsonReader);
return result;
}
}
}
??基類中Convert中將ResponseBody轉(zhuǎn)化成泛型T,子類GsonResponseConverter實(shí)現(xiàn)了Convert方法,該類持有TypeAdapter對(duì)象,真正轉(zhuǎn)化是在ObjectTypeAdapter中實(shí)現(xiàn)的。
// OkHttpCall
Response<T> parseResponse(okhttp3.Response rawResponse) throws IOException {
ResponseBody rawBody = rawResponse.body();
rawResponse =
rawResponse
.newBuilder()
.body(new NoContentResponseBody(rawBody.contentType(), rawBody.contentLength()))
.build();
int code = rawResponse.code();
ExceptionCatchingResponseBody catchingBody = new ExceptionCatchingResponseBody(rawBody);
try {
T body = responseConverter.convert(catchingBody);
return Response.success(body, rawResponse);
}
}
?? Adapter將stream轉(zhuǎn)化成需要的對(duì)象,比如DateBean,包轉(zhuǎn)成Response<DateBean>返回。
7、策略模式

3.1、解析注解,生成ParameterHandler
private ParameterHandler<?> parseParameterAnnotation(
int p, Type type, Annotation[] annotations, Annotation annotation) {
if (annotation instanceof FieldMap) {
validateResolvableType(p, type);
Class<?> rawParameterType = Utils.getRawType(type);
Type mapType = Utils.getSupertype(type, rawParameterType, Map.class);
ParameterizedType parameterizedType = (ParameterizedType) mapType;
Type keyType = Utils.getParameterUpperBound(0, parameterizedType);
Type valueType = Utils.getParameterUpperBound(1, parameterizedType);
Converter<?, String> valueConverter = retrofit.stringConverter(valueType, annotations);
gotField = true;
return new ParameterHandler.FieldMap<>(
method, p, valueConverter, ((FieldMap) annotation).encoded());
} else if (annotation instanceof Body) {
validateResolvableType(p, type);
Converter<?, RequestBody> converter;
try {
converter = retrofit.requestBodyConverter(type, annotations, methodAnnotations);
}
gotBody = true;
return new ParameterHandler.Body<>(method, p, converter);
}
}
3.2、實(shí)現(xiàn)ParameterHandler接口,重寫apply()方法
static final class FieldMap<T> extends ParameterHandler<Map<String, T>> {
private final Converter<T, String> valueConverter;
private final boolean encoded;
@Override
void apply(RequestBuilder builder, @Nullable Map<String, T> value) throws IOException {
for (Map.Entry<String, T> entry : value.entrySet()) {
String entryKey = entry.getKey();
T entryValue = entry.getValue();
String fieldEntry = valueConverter.convert(entryValue);
builder.addFormField(entryKey, fieldEntry, encoded);
}
}
}
3.3、使用ParameterHandler對(duì)象。
// OkHttpCall
private okhttp3.Call createRawCall() throws IOException {
okhttp3.Call call = callFactory.newCall(requestFactory.create(args));
return call;
}
// RequestFactory
okhttp3.Request create(Object[] args) throws IOException {
ParameterHandler<Object>[] handlers = (ParameterHandler<Object>[]) parameterHandlers;
int argumentCount = args.length;
RequestBuilder requestBuilder =
new RequestBuilder(
httpMethod,
baseUrl,
relativeUrl,
headers,
contentType,
hasBody,
isFormEncoded,
isMultipart);
List<Object> argumentList = new ArrayList<>(argumentCount);
for (int p = 0; p < argumentCount; p++) {
argumentList.add(args[p]);
handlers[p].apply(requestBuilder, args[p]);
}
return requestBuilder.get().tag(Invocation.class, new Invocation(method, argumentList)).build();
}
okhttp執(zhí)行同步或者異步請(qǐng)求時(shí),調(diào)用createRawCall方法,接著調(diào)用create方法,調(diào)用handlers[p].apply,將參數(shù)設(shè)置給requestBuilder,返回request。
總結(jié)
?? Retrofit使用到了很多模式,除了上述,還使用了比如常見模板設(shè)計(jì)模式,裝飾設(shè)計(jì)模式,原型模式、門面模式、觀察者模式等。