Retrofit 의 디자인 모델 - 동적 에이전트 모델
최근 에 시간 이 나 서 소스 코드 의 리듬 을 보기 시 작 했 습 니 다. Retrofit 소스 코드 를 보면 동적 에이전트 모델 을 볼 수 있 습 니 다. 그러나 엄 밀 히 말 하면 진정한 동적 에이전트 모델 이 아니 라 이것 이 야 말로 진정한 큰 소의 코드 이 고 임기응변 하 며 고정 모델 의 영향 을 받 지 않 습 니 다.
1. 정규 동적 에이전트 모델
/**
* Description:
*/
public interface RetrofitInterface {
String retrofitInterfaceFunc(String s);
}
/**
* Description:
*/
public class Retrofit implements RetrofitInterface {
@Override
public String retrofitInterfaceFunc(String s) {
System.out.printf("progress " + s + "
");
return s;
}
}
/**
* Description:
*/
public class RetrofitProxy {
private Retrofit retrofit;
public RetrofitProxy(Retrofit retrofit) {
this.retrofit = retrofit;
}
public T create(Class service){
if (!service.isInterface()){
throw new IllegalArgumentException("API declarations must be interfaces. ");
}
return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class[]{service},
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("before
");
method.invoke(retrofit, args);
// System.out.printf("function name: " + method.getName() + "
");
// System.out.printf("function return type: " + method.getReturnType().getName() + "
");
// System.out.printf("args name: " + args[0].toString() + "
");
System.out.printf("after
");
return null;
}
});
}
}
/**
* Description:
*/
public class TestMain {
public static void main(String[] args) {
RetrofitProxy proxy = new RetrofitProxy(new Retrofit());
RetrofitInterface retrofitInterface = proxy.create(RetrofitInterface.class);
retrofitInterface.retrofitInterfaceFunc("12345");
}
}
인쇄 결 과 는 다음 과 같 습 니 다.
before
progress 12345
after
Process finished with exit code 0
이 인터넷 들 은 매우 많 습 니 다. 주로 Retrofit 의 동적 에이전트 와 비교 가 됩 니 다. 2. Retrofit 의 동적 대 리 는 먼저 우리 가 사용 할 때 호출 인 터 페 이 스 를 씁 니 다.
public interface RetrofitService {
@Headers({"Content-type:application/json;charset=UTF-8"})
@GET("data/{type}/20/{page}")
Observable>> getNewsList(@Path("type") String type, @Path("page") int page);
}
지금 문제 가 생 겼 습 니 다. 우 리 는 뒤의 코드 에서 이 인 터 페 이 스 를 진정 으로 실현 한 적 이 없습니다. Retrofit 는 어떻게 동적 대 리 를 합 니까? 우리 가 뒤에 사용 하 는 이 인터페이스 가 바로 이 렇 습 니 다.
retrofit.create(RetrofitService.class);
따라 들 어가 보 자.
public T create(final Class 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, 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);
}
ServiceMethod serviceMethod = loadServiceMethod(method);
OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args);
return serviceMethod.callAdapter.adapt(okHttpCall);
}
});
}
진정 으로 작용 하 는 것 은
ServiceMethod serviceMethod = loadServiceMethod(method);
OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args);
return serviceMethod.callAdapter.adapt(okHttpCall);
그러나 우 리 는 method. invoke 라 는 글 자 를 전혀 보지 못 했다. (앞의 것 은 아니 고 잘못 사용 한 판단 일 뿐이다) 사실은 여기 서 Retrofit 가 정규 적 인 동적 대 리 를 실현 하지 못 했다 는 것 을 생각 할 수 있다. 왜냐하면 우 리 는 대 리 를 요구 하 는 대상 이 들 어 오지 않 았 기 때문이다. 그 가 이렇게 쓰 는 것 은 바로 동태 대리 의 특성 으로 자신 이 원 하 는 데 이 터 를 얻 은 다음 에 그의 생각 에 따라(향 원 모드 구축 요청) 앞의 Demo 를 Retrofit 와 유사 한 상황 으로 바 꿀 수 있 습 니 다. 3. Retrofit 개조 후의 Demo 를 모방 할 수 있 습 니 다.
/**
* Description:
*/
public class RetrofitProxy {
// private Retrofit retrofit;
//
// public RetrofitProxy(Retrofit retrofit) {
// this.retrofit = retrofit;
// }
public static T create(Class service){
if (!service.isInterface()){
throw new IllegalArgumentException("API declarations must be interfaces. ");
}
return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class[]{service},
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("before
");
// method.invoke(retrofit, args);
System.out.printf("function name: " + method.getName() + "
");
System.out.printf("function return type: " + method.getReturnType().getName() + "
");
System.out.printf("args name: " + args[0].toString() + "
");
System.out.printf("after
");
return null;
}
});
}
}
/**
* Description:
*/
public class TestMain {
public static void main(String[] args) {
// RetrofitProxy proxy = new RetrofitProxy(new Retrofit());
RetrofitInterface retrofitInterface = RetrofitProxy.create(RetrofitInterface.class);
retrofitInterface.retrofitInterfaceFunc("12345");
}
}
실행 결 과 는 다음 과 같 습 니 다.
before
function name: retrofitInterfaceFunc
function return type: java.lang.String
args name: 12345
after
Process finished with exit code 0
프 록 시 대상 이 전달 되 지 않 았 지만 동적 프 록 시 특성 을 사용 하여 인터페이스 에 있 는 모든 인 자 를 가 져 와 자신의 일 을 실현 했다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.