改装-在执行调用时运行自定义逻辑



我正在使用Reform在Spring启动应用程序中执行HTTP调用。

每当API调用被执行时,我都试图找到一种让我的自定义代码运行的方法。

在我的自定义代码的上下文中,我需要知道哪个方法调用了这个API调用。

我能想出三个解决方案,但每一个都有问题。

让我们使用下面的示例代码,假设我有

public interface MyClient {
@GET("myurl")
Call<MyDto> getInfo();
}
@Bean
public MyClient getMyClient() {
Retrofit myRetrofit = new Retrofit.Builder()
.baseUrl(myBaseUrl)
.client(oauthOkHttpClient())
.addConverterFactory(jacksonConverterFactory)
.build();
return myRetrofit.create(MyClient.class);
}
Call<MyDto> apiCall = myClient.getInfo();
apiCall.clone().execute()

我希望我的代码在调用execute后运行。

三种解决方案:

1.使用@Aspect

这有可能让我访问调用方法并运行自定义逻辑。

问题是,虽然接口是一个Spring组件,但执行调用的代码不是。

还有办法让这样的东西发挥作用吗?

@Aspect
@Order(3)
@GlobalComponent
public class MyAspect {
@Around("execution(* retrofit2.Call.execute())(..))")
public void runLogic(ProceedingJoinPoint joinPoint) {
do(...)
}
}

2.实现okhttp3拦截器

由于myReform使用oauthOkHttpClient(请参阅构建器(,因此在进行调用时会激活拦截器。

这里的问题是,我在拦截器中只有okhttp3响应,我看不出谁是调用方法和类(MyClient.getInfo(

3.提供回电

apiCall.enqueue(new Callback<>() {
@Override
public void onResponse(Call<MyDto> call, Response<MyDto> response) {}
@Override
public void onFailure(Call<MyDto> call, Throwable t) {}
});

is选项的问题与第二个选项类似。找不到获取调用程序的方法。

有什么想法吗?

我找到了一种方法。

您需要创建自己的CallAdapter.Factory,并在创建客户端时将其传递给改装生成器。

这里有一个例子:

Retrofit accountsRetrofit = new Retrofit.Builder()
.baseUrl(baseUrl)
.client(client)
.addConverterFactory(converterFactory)
.addCallAdapterFactory(new MyAdapterFactory())
.build();

定制工厂:

public class MyAdapterFactory extends CallAdapter.Factory {
@Nullable
@Override
public CallAdapter<?, ?> get(@NotNull Type returnType, @NotNull Annotation[] annotations, Retrofit retrofit) {
CallAdapter<?, ?> nextCallAdapter = retrofit.nextCallAdapter(this, returnType, annotations);
return new MonitorCallAdapter<>(nextCallAdapter);
}
private static final class MonitorCallAdapter<R, T> implements CallAdapter<R, T> {
private final CallAdapter<?, ?> nextCallAdapter;
private MonitorCallAdapter(CallAdapter<?, ?> nextCallAdapter) {
this.nextCallAdapter = nextCallAdapter;
}
@NotNull
@Override
public Type responseType() {
return nextCallAdapter.responseType();
}
@NotNull
@Override
public T adapt(@NotNull Call<R> call) {
return (T) nextCallAdapter.adapt(new MonitoredCall(call));
}
}
private static final class MonitoredCall<T> implements Call<T> {
private final Call<T> wrappedCall;
private MonitoredCall(Call<T> call) {
this.wrappedCall = call;
}
@NotNull
@Override
public Response<T> execute() throws IOException { 
////PUT_CUSTOM_LOGIC_HERE
return wrappedCall.execute();
}
@Override
public void enqueue(@NotNull Callback<T> callback) {
wrappedCall.enqueue(new Callback<T>() {
@Override
public void onResponse(@NotNull Call<T> call, @NotNull Response<T> response) {
callback.onResponse(call, response);
}
@Override
public void onFailure(@NotNull Call<T> call, @NotNull Throwable t) {
callback.onFailure(call, t);
}
});
}
@Override
public boolean isExecuted() {
return wrappedCall.isExecuted();
}
@Override
public void cancel() {
wrappedCall.cancel();
}
@Override
public boolean isCanceled() {
return wrappedCall.isCanceled();
}
@Override
public Call<T> clone() {
return new MonitoredCall<T>(wrappedCall.clone());
}
@Override
public Request request() {
return wrappedCall.request();
}
}
}

最新更新