retrofit 源碼分析
- retrofit 源碼分析
源碼執(zhí)行流程
new Retrofit.Builder().baseUrl(xx).build()
基于retrofit 2.4.1
Retrofit.Builder()
創(chuàng)建retrofit實例對象卜朗,通過new Retrofit.Builder().build()
;Builder作為Retrofit的靜態(tài)內部類
Retrofit.Builder類有3個構造函數(shù),分別為
public static final class Builder {
...
Builder(Platform platform) {
this.platform = platform;
}
public Builder() {
this(Platform.get());
}
Builder(Retrofit retrofit) { ... }
...
}
只有無參的構造函數(shù)提供了外部訪問權限public
,其它兩個都是包內訪問;通過platform.get()
獲取Platform對象,我在android平臺使用涵卵,所以返回的是Android
;代碼如下
class Platform {
private static final Platform PLATFORM = findPlatform();
static Platform get(){
return PLATFORM;
}
private static Platform findPlatform() {
try {
Class.forName("android.os.Build");
if (Build.VERSION.SDK_INT != 0) {
return new Android();
}
} catch (ClassNotFoundException ignored) {
}
try {
Class.forName("java.util.Optional");
return new Java8();
} catch (ClassNotFoundException ignored) {
}
return new Platform();
}
}
baseUrl
Retrofit.Builder類中方法遵循鏈式調用規(guī)則(即方法返回this,使用.
調用下一個方法)卸留;例如
...
public Builder addConverterFactory(Converter.Factory factory){
converterFactories.add(checkNotNull(factory,"factory == null"));
return this;
}
public Builder callbackExecutor(Executor executor) {
this.callbackExecutor = checkNotNull(executor, "executor == null");
return this;
}
...
baseUrl
必須以'/'結尾
build()
Retrofit.Builder().build()
通過建造者模式
陶缺,創(chuàng)建Retrofit對象狈癞;
對相關變量進行初始化夯到,有CallFactory
,CallAdapter.Factory
,Converter.Factory
,Executor
,并以此為參數(shù)創(chuàng)建Retrofit
public Retrofit build() {
if (baseUrl == null) {
throw new IllegalStateException("Base URL required.");
}
//CallFactory = OkHttpClient
okhttp3.Call.Factory callFactory = this.callFactory;
if (callFactory == null) {
callFactory = new OkHttpClient();
}
//Executor = Android.MainThreadExecutor
Executor callbackExecutor = this.callbackExecutor;
if (callbackExecutor == null) {
callbackExecutor = platform.defaultCallbackExecutor();
}
//CallAdapter.Factory = ExecutorCallAdapterFactory
List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
callAdapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));
//Converter.Factory = BuiltInConverters
List<Converter.Factory> converterFactories =
new ArrayList<>(1 + this.converterFactories.size());
converterFactories.add(new BuiltInConverters());
converterFactories.addAll(this.converterFactories);
return new Retrofit(callFactory, baseUrl, unmodifiableList(converterFactories),
unmodifiableList(callAdapterFactories), callbackExecutor, validateEagerly);
}
Platform.Android源碼:它是Platform的子類枣申,且是靜態(tài)內部類售葡;
static class Android extends Platform {
@IgnoreJRERequirement // Guarded by API check.
@Override boolean isDefaultMethod(Method method) {
if (Build.VERSION.SDK_INT < 24) {
return false;
}
return method.isDefault(); //false
}
@Override public Executor defaultCallbackExecutor() {
return new MainThreadExecutor();
}
@Override CallAdapter.Factory defaultCallAdapterFactory(@Nullable Executor callbackExecutor) {
if (callbackExecutor == null) throw new AssertionError();
return new ExecutorCallAdapterFactory(callbackExecutor);
}
static class MainThreadExecutor implements Executor {
private final Handler handler = new Handler(Looper.getMainLooper());
@Override public void execute(Runnable r) {
handler.post(r);
}
}
}
IHttp ihttp = retrofit.create(IHttp.class)
IHttp
為使用者自定義接口,我自定義了post
方法
public interface IHttp {
@POST("{url}")
Call<ResponseBody> post(@Path(value = "url", encoded = true) String url,
@HeaderMap Map<String, String> headers,
@Body RequestBody body);
}
create()
通過retrofit.create
獲取接口實例對象,此處使用了動態(tài)代理設計模式
public <T> T create(final Class<T> service) {
Utils.validateServiceInterface(service);
if (validateEagerly) {
eagerlyValidateMethods(service);
}
return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service },
new InvocationHandler() {
private final Platform platform = Platform.get();
@Override public Object invoke(Object proxy, Method method, @Nullable Object[] args)
throws Throwable {
// If the method is a method from Object then defer to normal invocation.
if (method.getDeclaringClass() == Object.class) {
return method.invoke(this, args);
}
if (platform.isDefaultMethod(method)) {
return platform.invokeDefaultMethod(method, service, proxy, args);
}
return loadServiceMethod(method).invoke(args);
}
});
}
其中,method.getDeclaringClass
返回IHttp中post方法的返回值類型忠藤;
ServiceMethod<?> loadServiceMethod(Method method) {
ServiceMethod<?> result = serviceMethodCache.get(method);
if (result != null) return result;
synchronized (serviceMethodCache) {
result = serviceMethodCache.get(method);
if (result == null) {
result = ServiceMethod.parseAnnotations(this, method);
serviceMethodCache.put(method, result);
}
}
return result;
}
執(zhí)行接口方法,得到Call<ResponseBody>
調用接口的方法ihttp.post()
挟伙,得到返回值;源碼中執(zhí)行到proxy.invoke()
; loadServiceMethod()
,最后執(zhí)行到serviceMethod.invoke()
;
ServiceMethod
ServiceMethod是抽象類模孩,子類是HttpServiceMethod
; 同樣通過建造者模式獲取HttpServiceMethod對象
abstract class ServiceMethod<T> {
static <T> ServiceMethod<T> parseAnnotations(Retrofit retrofit, Method method) {
Type returnType = method.getGenericReturnType();
if (Utils.hasUnresolvableType(returnType)) {
throw methodError(method,
"Method return type must not include a type variable or wildcard: %s", returnType);
}
if (returnType == void.class) {
throw methodError(method, "Service methods cannot return void.");
}
return new HttpServiceMethod.Builder<Object, T>(retrofit, method).build();
}
abstract T invoke(@Nullable Object[] args);
}
//HttpServiceMethod.Builder像寒, 構造函數(shù)參數(shù)來源:method: Proxy.invoke的第二個參數(shù)
Builder(Retrofit retrofit, Method method) {
this.retrofit = retrofit;
this.method = method;
}
HttpServiceMethod<ResponseT, ReturnT> build() {
requestFactory = RequestFactory.parseAnnotations(retrofit, method);//[1]
callAdapter = createCallAdapter();//[2]
responseType = callAdapter.responseType();
if (responseType == Response.class || responseType == okhttp3.Response.class) {
throw methodError(method, "'"
+ Utils.getRawType(responseType).getName()
+ "' is not a valid response body type. Did you mean ResponseBody?");
}
responseConverter = createResponseConverter();//[3]
if (requestFactory.httpMethod.equals("HEAD") && !Void.class.equals(responseType)) {
throw methodError(method, "HEAD method must use Void as response type.");
}
return new HttpServiceMethod<>(this);
}
[1]requestFactory:解析網絡請求方式及請求地址路徑
在HttpServiceMethod.Builder.build()方法中烘豹,有解析注解的函數(shù)調用[1] requestFactory = RequestFactory.parseAnnotations(retrofit, method);
final class RequestFactory {
static RequestFactory parseAnnotations(Retrofit retrofit, Method method) {
return new Builder(retrofit, method).build();
}
}
//RequestFactory.Builder的構造函數(shù)只進行了變量賦值,此處省略代碼
RequestFactory build(){
for (Annotation annotation : methodAnnotations){
parseMethodAnnotation(annotation);
}
...
return new RequestFactory(this);
}
private void parseMethodAnnotation(Annotation annotation) {
if (annotation instanceof DELETE) {
parseHttpMethodAndPath("DELETE", ((DELETE) annotation).value(), false);
}else if (annotation instanceof POST) { //我使用post
parseHttpMethodAndPath("POST", ((POST) annotation).value(), true); //.value取出url地址诺祸;path路徑
}
...
}
private void parseHttpMethodAndPath(String httpMethod, String value, boolean hasBody) {
if (this.httpMethod != null) {
throw methodError(method, "Only one HTTP method is allowed. Found: %s and %s.",
this.httpMethod, httpMethod);
}
this.httpMethod = httpMethod;
this.hasBody = hasBody;
if (value.isEmpty()) {
return;
}
// Get the relative URL path and existing query string, if present.
int question = value.indexOf('?');
if (question != -1 && question < value.length() - 1) {
// Ensure the query string does not have any named parameters.
String queryParams = value.substring(question + 1);
Matcher queryParamMatcher = PARAM_URL_REGEX.matcher(queryParams);
if (queryParamMatcher.find()) {
throw methodError(method, "URL query string \"%s\" must not have replace block. "
+ "For dynamic query parameters use @Query.", queryParams);
}
}
this.relativeUrl = value;//通過注解取出
this.relativeUrlParamNames = parsePathParameters(value);
}
[2]創(chuàng)建CallAdapter對象
在HttpServiceMethod.Builder.build()方法中外构,調用[2]創(chuàng)建CallAdapter對象
callAdapter = createCallAdapter();
,實際上通過retrofit中CallAdapter.Factory
變量獲取,也就是ExecutorCallAdapterFactory.get()
//HttpServiceMethod.Builder
private CallAdapter<ResponseT, ReturnT> createCallAdapter() {
Type returnType = method.getGenericReturnType();
Annotation[] annotations = method.getAnnotations();
try {
return (CallAdapter<ResponseT, ReturnT>) retrofit.callAdapter(returnType, annotations);
} catch (RuntimeException e) {
throw methodError(method, e, "Unable to create call adapter for %s", returnType);
}
}
//Retrofit
public CallAdapter<?, ?> callAdapter(Type returnType, Annotation[] annotations) {
return nextCallAdapter(null, returnType, annotations);
}
//adapter= ExecutorCallAdapterFactory.get()
public CallAdapter<?, ?> nextCallAdapter(@Nullable CallAdapter.Factory skipPast, Type returnType,
Annotation[] annotations) {
checkNotNull(returnType, "returnType == null");
checkNotNull(annotations, "annotations == null");
int start = callAdapterFactories.indexOf(skipPast) + 1;
for (int i = start, count = callAdapterFactories.size(); i < count; i++) {
CallAdapter<?, ?> adapter = callAdapterFactories.get(i).get(returnType, annotations, this);//ExecutorCallAdapterFactory.get()
if (adapter != null) {
return adapter;
}
}
final class ExecutorCallAdapterFactory extends CallAdapter.Factory{
...
@Override
public CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
if (getRawType(returnType) != Call.class) {
return null;
}
final Type responseType = Utils.getCallResponseType(returnType);
//這就是HttpServiceMethod中的callAdapter
return new CallAdapter<Object, Call<?>>() {
@Override public Type responseType() {
return responseType;
}
@Override public Call<Object> adapt(Call<Object> call) {
return new ExecutorCallbackCall<>(callbackExecutor, call);
}
};
}
...
}
[3]創(chuàng)建Converter對象
在HttpServiceMethod.Builder.build()方法中,調用[3]創(chuàng)建Converter對象
responseConverter = createResponseConverter()
實際上調用retrofit中的BuiltInConverters.responseBodyConverter
//HttpServiceMethod.Builder.java
private Converter<ResponseBody, ResponseT> createResponseConverter() {
Annotation[] annotations = method.getAnnotations();
try {
return retrofit.responseBodyConverter(responseType, annotations);
} catch (RuntimeException e) {
throw methodError(method, e, "Unable to create converter for %s", responseType);
}
}
//Retrofit.java
//Converter = BuiltInConverters.responseBodyConverter()
public <T> Converter<ResponseBody, T> responseBodyConverter(Type type, Annotation[] annotations) {
return nextResponseBodyConverter(null, type, annotations);
}
public <T> Converter<ResponseBody, T> nextResponseBodyConverter(
@Nullable Converter.Factory skipPast, Type type, Annotation[] annotations) {
checkNotNull(type, "type == null");
checkNotNull(annotations, "annotations == null");
int start = converterFactories.indexOf(skipPast) + 1;
for (int i = start, count = converterFactories.size(); i < count; i++) {
Converter<ResponseBody, ?> converter =
converterFactories.get(i).responseBodyConverter(type, annotations, this);//BuiltInConverters.responseBodyConverter()
if (converter != null) {
//noinspection unchecked
return (Converter<ResponseBody, T>) converter;
}
}
//BuiltInConverters.java
// converter = BufferingResponseBodyConverter.INSTANCE
final class BuiltInConverters extends Converter.Factory {
@Override
public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations,
Retrofit retrofit) {
if (type == ResponseBody.class) {
return Utils.isAnnotationPresent(annotations, Streaming.class)
? StreamingResponseBodyConverter.INSTANCE
: BufferingResponseBodyConverter.INSTANCE;
}//
if (type == Void.class) {
return VoidResponseBodyConverter.INSTANCE;
}
return null;
}
...
}
以上分析完ServiceMethod
創(chuàng)建過程漠酿,主要節(jié)點在[1][2][3]中
動態(tài)代理invoke的執(zhí)行邏輯
loadServiceMethod(method).invoke(args)
loadServiceMethod()
返回ServiceMethod對象赫粥,其invoke
為抽象方法,子類HttpServiceMethod.invoke
的具體實現(xiàn)如下
//HttpServiceMethod.java
@Override ReturnT invoke(@Nullable Object[] args) {
return callAdapter.adapt(
new OkHttpCall<>(requestFactory, args, callFactory, responseConverter));
}
//callAdapter為[2]ExecutorCallAdapterFactory.get()
//requestFacotry為[1]
//callFactory為retrofit.callFactory,就是Retrofit.Builder中的OkHttpClient
//responseConverter為[3]
final class OkHttpCall<T> implements Call<T>
//ExecutorCallAdapterFactory.java
@Override
public CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
...
return new CallAdapter<Object, Call<?>>() {
@Override public Type responseType() {
return responseType;
}
//callbackExecutor為retrofit.callbackExecutor胃夏,就是Android.MainThreadExecutor
//call: OkHttpCall
@Override public Call<Object> adapt(Call<Object> call) {
return new ExecutorCallbackCall<>(callbackExecutor, call);
}
};
}
static final class ExecutorCallbackCall<T> implements Call<T> {
...
}
在自定義的IHttp接口中轴或,post請求返回值為Call<ResponseBody>
, ExecutorCallbackCall
即是該返回值
執(zhí)行網絡請求
通過執(zhí)行ihttp.post()
得到的Call對象,執(zhí)行call.enqueue()
enqueue
為異步請求仰禀;execute
為同步請求
call.enqueue
ExecutorCallbackCall代碼如下,是ExecutorCallAdapterFactory的內部類
//ExecutorCallAdapterFactory.java
static final class ExecutorCallbackCall<T> implements Call<T> {
...
//callbackExecutor為retrofit.callbackExecutor照雁,就是Android.MainThreadExecutor
//delegate: OkHttpCall
ExecutorCallbackCall(Executor callbackExecutor, Call<T> delegate) {
this.callbackExecutor = callbackExecutor;
this.delegate = delegate;
}
//callback:由使用者傳入,網絡請求回調
@Override public void enqueue(final Callback<T> callback) {
checkNotNull(callback, "callback == null");
delegate.enqueue(new Callback<T>() {
@Override public void onResponse(Call<T> call, final Response<T> response) {
...
}
@Override public void onFailure(Call<T> call, final Throwable t) {
... }
});
}
...
}
調用okhttp
OkHttpCall調用okhttp中api實現(xiàn)網絡請求答恶,并接收請求結果
//OkHttpCall.java
@Override
public void enqueue(final Callback<T> callback) {
checkNotNull(callback, "callback == null");
okhttp3.Call call;
Throwable failure;
synchronized (this) {
if (executed) throw new IllegalStateException("Already executed.");
executed = true;
call = rawCall;
failure = creationFailure;
if (call == null && failure == null) {
try {
call = rawCall = createRawCall();//[1]
} catch (Throwable t) {
throwIfFatal(t);
failure = creationFailure = t;
}
}
}
if (failure != null) {
callback.onFailure(this, failure);
return;
}
if (canceled) {
call.cancel();
}
call.enqueue(new okhttp3.Callback() { //[2]
@Override public void onResponse(okhttp3.Call call, okhttp3.Response rawResponse) {
Response<T> response;
try {
response = parseResponse(rawResponse);//[3]
} catch (Throwable e) {
throwIfFatal(e);
callFailure(e);
return;
}
try {
callback.onResponse(OkHttpCall.this, response);
} catch (Throwable t) {
t.printStackTrace();
}
}
@Override public void onFailure(okhttp3.Call call, IOException e) {
callFailure(e);
}
private void callFailure(Throwable e) {
try {
callback.onFailure(OkHttpCall.this, e);
} catch (Throwable t) {
t.printStackTrace();
}
}
});
}
//callFactory : OkHttpClient, retrofit中創(chuàng)建饺蚊,HttpServiceMethodz中傳入
//[1]
private okhttp3.Call createRawCall() throws IOException {
okhttp3.Call call = callFactory.newCall(requestFactory.create(args));
if (call == null) {
throw new NullPointerException("Call.Factory returned null.");
}
return call;
}
此處對requestFactory.create(args)
進行說明
//RequestFactory.java
okhttp3.Request create(@Nullable Object[] args) throws IOException {
RequestBuilder requestBuilder = new RequestBuilder(httpMethod, baseUrl, relativeUrl, headers,
contentType, hasBody, isFormEncoded, isMultipart);
@SuppressWarnings("unchecked") // It is an error to invoke a method with the wrong arg types.
ParameterHandler<Object>[] handlers = (ParameterHandler<Object>[]) parameterHandlers;
int argumentCount = args != null ? args.length : 0;
if (argumentCount != handlers.length) {
throw new IllegalArgumentException("Argument count (" + argumentCount
+ ") doesn't match expected count (" + handlers.length + ")");
}
for (int p = 0; p < argumentCount; p++) {
handlers[p].apply(requestBuilder, args[p]);
}
return requestBuilder.build();
}
requestBuilder.build()
函數(shù)內調用okhttp3中api,拼裝請求信息
//[2]:通過okhttp3執(zhí)行enqueue,并創(chuàng)建okhttp3.Callback
//[3]:解析返回值
Response<T> parseResponse(okhttp3.Response rawResponse) throws IOException {
ResponseBody rawBody = rawResponse.body();
// Remove the body's source (the only stateful object) so we can pass the response along.
rawResponse = rawResponse.newBuilder()
.body(new NoContentResponseBody(rawBody.contentType(), rawBody.contentLength()))
.build();
int code = rawResponse.code();
if (code < 200 || code >= 300) {
try {
// Buffer the entire body to avoid future I/O.
ResponseBody bufferedBody = Utils.buffer(rawBody);
return Response.error(bufferedBody, rawResponse);
} finally {
rawBody.close();
}
}
if (code == 204 || code == 205) {
rawBody.close();
return Response.success(null, rawResponse);
}
ExceptionCatchingResponseBody catchingBody = new ExceptionCatchingResponseBody(rawBody);
try {
T body = responseConverter.convert(catchingBody);//[4]
return Response.success(body, rawResponse);
} catch (RuntimeException e) {
// If the underlying source threw an exception, propagate that rather than indicating it was
// a runtime exception.
catchingBody.throwIfCaught();
throw e;
}
}
//[4]responseConverter為BuiltInConverters.responseBodyConverter(),本次分析使用的是BufferingResponseBodyConverter
//BuiltInConverters.java
static final class BufferingResponseBodyConverter
implements Converter<ResponseBody, ResponseBody> {
static final BufferingResponseBodyConverter INSTANCE = new BufferingResponseBodyConverter();
@Override public ResponseBody convert(ResponseBody value) throws IOException {
try {
// Buffer the entire body to avoid future I/O.
return Utils.buffer(value);
} finally {
value.close();
}
}
}
//Utils.java, 此處涉及okhttp3悬嗓,下篇討論
static ResponseBody buffer(final ResponseBody body) throws IOException {
Buffer buffer = new Buffer();//com.squareup.okio
body.source().readAll(buffer);
return ResponseBody.create(body.contentType(), body.contentLength(), buffer);
}
回調
在ExecutorCallbackCall中污呼,delegate.enqueue
傳入了匿名對象callback
,匿名對象中由callbackExecutor.execute
調用使用值傳入的callback
//ExecutorCallbackCall.class
@Override public void enqueue(final Callback<T> callback) {
checkNotNull(callback, "callback == null");
delegate.enqueue(new Callback<T>() {
@Override public void onResponse(Call<T> call, final Response<T> response) {
callbackExecutor.execute(new Runnable() {
@Override public void run() {
if (delegate.isCanceled()) {
// Emulate OkHttp's behavior of throwing/delivering an IOException on cancellation.
callback.onFailure(ExecutorCallbackCall.this, new IOException("Canceled"));
} else {
callback.onResponse(ExecutorCallbackCall.this, response);
}
}
});
}
@Override public void onFailure(Call<T> call, final Throwable t) {
callbackExecutor.execute(new Runnable() {
@Override public void run() {
callback.onFailure(ExecutorCallbackCall.this, t);
}
});
}
});
}
//callbackExecutor為retrofit.callbackExecutor,就是Android.MainThreadExecutor
//Platform.java
static class MainThreadExecutor implements Executor {
private final Handler handler = new Handler(Looper.getMainLooper());
@Override public void execute(Runnable r) {
handler.post(r);
}
}
至此,已分析完retrofit源碼包竹,其中核心邏輯涉及okhttp3燕酷,會單獨寫一篇進行分析
源碼設計模式
建造者模式(Builder Pattern)
將一個復雜對象的構建與它的表示分離,使同樣的構建過程可以創(chuàng)建不同的表示.
屬于創(chuàng)建型模式周瞎,它提供了一種創(chuàng)建對象的最佳方式苗缩。
何時使用:
- 一些基本部件不會變,而其組合經常變化的時候声诸。
優(yōu)點:
- 建造者獨立酱讶,易擴展
- 便于控制細節(jié)風險
缺點:
- 產品必須有共同點,范圍有限制
- 如內部變化復雜双絮,會有很多的建造類
注意事項:與工廠模式的區(qū)別是:建造者模式更加關注與零件裝配的順序
結合retrofit源碼中的使用場景浴麻,進行舉例
retrofit中Retrofit
和HttpServiceMethod
對象的創(chuàng)建就是通過建造者模式;
實現(xiàn)方式: 在類中創(chuàng)建靜態(tài)內部類Builder囤攀,Builder提供外部訪問權限软免,定義相關變量的set方法,并定義build
函數(shù)最終創(chuàng)建外部類對象. Builder中函數(shù)遵循鏈式調用規(guī)則
//Retrofit.java
public static final class Builder {
public Builder() {...}
public Builder callFactory(okhttp3.Call.Factory factory) {
this.callFactory = checkNotNull(factory, "factory == null");
return this;
}
public Builder callbackExecutor(Executor executor) {
this.callbackExecutor = checkNotNull(executor, "executor == null");
return this;
}
...
//創(chuàng)建外部類對象
public Retrofit build() {
if (baseUrl == null) {
throw new IllegalStateException("Base URL required.");
}
okhttp3.Call.Factory callFactory = this.callFactory;
if (callFactory == null) {
callFactory = new OkHttpClient();
}
Executor callbackExecutor = this.callbackExecutor;
if (callbackExecutor == null) {
callbackExecutor = platform.defaultCallbackExecutor();
}
List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
callAdapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));
List<Converter.Factory> converterFactories =
new ArrayList<>(1 + this.converterFactories.size());
converterFactories.add(new BuiltInConverters());
converterFactories.addAll(this.converterFactories);
//給各變量賦值焚挠,并以此為參數(shù)創(chuàng)建Retrofit對象
return new Retrofit(callFactory, baseUrl, unmodifiableList(converterFactories),
unmodifiableList(callAdapterFactories), callbackExecutor, validateEagerly);
}
}
//Retrofit構造函數(shù)可見性為`default`,本包內可見
Retrofit(okhttp3.Call.Factory callFactory, HttpUrl baseUrl,
List<Converter.Factory> converterFactories, List<CallAdapter.Factory> callAdapterFactories,
@Nullable Executor callbackExecutor, boolean validateEagerly) {
this.callFactory = callFactory;
this.baseUrl = baseUrl;
this.converterFactories = converterFactories; // Copy+unmodifiable at call site.
this.callAdapterFactories = callAdapterFactories; // Copy+unmodifiable at call site.
this.callbackExecutor = callbackExecutor;
this.validateEagerly = validateEagerly;
}
如果參數(shù)過多或不統(tǒng)一膏萧,可使用Builder為參數(shù)創(chuàng)建外部類,如HttpServiceMethod的創(chuàng)建方式
//HttpServiceMethod.java
static final class Builder<ResponseT, ReturnT> {
...
HttpServiceMethod<ResponseT, ReturnT> build() {
...
return new HttpServiceMethod<>(this);
}
}
HttpServiceMethod(Builder<ResponseT, ReturnT> builder) {
requestFactory = builder.requestFactory;
callFactory = builder.retrofit.callFactory();
callAdapter = builder.callAdapter;
responseConverter = builder.responseConverter;
}
代理模式(Proxy Pattern)
屬于結構型模式
為其他對象提供一種代理以控制對這個對象的訪問
何時使用:
- 程序可能不希望用戶直接訪問該對象,而是提供一個特殊的對象以控制對當前對象的訪問
- 如果對象位于遠程主機上榛泛,需要為用戶提供訪問該遠程對象的能力
- 如果一個對象(例如很大的圖像)需要很長時間才能完成加載
優(yōu)點:
- 代理模式可以屏蔽用戶真正請求的對象蝌蹂,是用戶程序和正在的對象解耦
- 使用代理來擔當那些創(chuàng)建耗時的對象的替身
缺點:
代理類和委托類實現(xiàn)相同的接口,同時要實現(xiàn)相同的方法曹锨。這樣就出現(xiàn)了大量的代碼重復孤个。如果接口增加一個方法,除了所有實現(xiàn)類需要實現(xiàn)這個方法外沛简,所有代理類也需要實現(xiàn)此方法齐鲤。增加了代碼維護的復雜度。
靜態(tài)代理
需要定義接口或者父類,被代理對象與代理對象一起實現(xiàn)相同的接口或者是繼承相同父類.
注意:代理對象與目標對象要實現(xiàn)相同的接口,然后通過調用相同的方法來調用目標對象的方法
public interface IUserDao {
void save();
}
//目標對象
public class UserDao implements IUserDao {
public void save() {
System.out.println("----已經保存數(shù)據!----");
}
}
//代理對象
public class UserDaoProxy implements IUserDao{
//接收保存目標對象
private IUserDao target;
public UserDaoProxy(IUserDao target){
this.target=target;
}
public void save() {
System.out.println("開始事務...");
target.save();//執(zhí)行目標對象的方法
System.out.println("提交事務...");
}
}
public class App {
public static void main(String[] args) {
//目標對象
UserDao target = new UserDao();
//代理對象,把目標對象傳給代理對象,建立代理關系
UserDaoProxy proxy = new UserDaoProxy(target);
proxy.save();//執(zhí)行的是代理的方法
}
}
動態(tài)代理
也叫JDK代理,接口代理
- 在運行期椒楣,通過反射機制創(chuàng)建一個實現(xiàn)了一組給定接口的新類
- 接口中聲明的所有方法都被轉移到調用處理器一個集中的方法中處理(InvocationHandler.invoke).在接口方法數(shù)量比較多的時候给郊,我們可以進行靈活處理,而不需要像靜態(tài)代理那樣每一個方法進行中轉捧灰。而且動態(tài)代理的應用使我們的類職責更加單一淆九,復用性更強
- 在運行時生成的class,必須提供一組interface給它毛俏,然后該class就宣稱它實現(xiàn)了這些 interface
代理類所在包:java.lang.reflect.Proxy
static Object newProxyInstance(ClassLoader loader, Class [] interfaces, InvocationHandler handler)
注意該方法是在Proxy類中是靜態(tài)方法,且接收的三個參數(shù)依次為:
- ClassLoader loader:指定當前目標對象使用類加載器,用null表示默認類加載器
- Class [] interfaces:需要實現(xiàn)的接口數(shù)組
- InvocationHandler handler:調用處理器,執(zhí)行目標對象的方法時,會觸發(fā)調用處理器的方法,從而把當前執(zhí)行目標對象的方法作為參數(shù)傳入
java.lang.reflect.InvocationHandler
:這是調用處理器接口炭庙,它自定義了一個 invoke 方法,用于集中處理在動態(tài)代理類對象上的方法調用拧抖,通常在該方法中實現(xiàn)對委托類的代理訪問煤搜。
// 該方法負責集中處理動態(tài)代理類上的所有方法調用免绿。第一個參數(shù)既是代理類實例唧席,第二個參數(shù)是被調用的方法對象
// 第三個方法是調用參數(shù)。
Object invoke(Object proxy, Method method, Object[] args)
retrofit中就是使用了動態(tài)代理模式嘲驾,調用時傳入.class
對象,返回接口實例對象
//Retrofit.java
public <T> T create(final Class<T> service) {
...
return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service },
new InvocationHandler() {
private final Platform platform = Platform.get();
@Override public Object invoke(Object proxy, Method method, @Nullable Object[] args)
throws Throwable {
// If the method is a method from Object then defer to normal invocation.
if (method.getDeclaringClass() == Object.class) {
return method.invoke(this, args);
}
if (platform.isDefaultMethod(method)) {
return platform.invokeDefaultMethod(method, service, proxy, args);
}
return loadServiceMethod(method).invoke(args);
}
});
}
//IHttp為自定義接口
IHttp ihttp = retrofit.create(IHttp.class);