OkHttp拦截器使用OkHttpClient而没有依赖循环

时间:2015-11-10 14:56:55

标签: android dependency-injection retrofit okhttp dagger-2

我正在使用Retrofit和Dagger 2.我已经实现了一个OkHttp Interceptor来添加oauth令牌。如果没有oauth令牌或时间戳无效,我会在执行实际请求之前请求新的(通过Retrofit服务)。

这会创建一个依赖循环,其中Retrofit服务需要Interceptor,但Interceptor也需要Retrofit服务(用于检索oauth令牌)。

Interceptor的示例(为了简化它总是通过restService#refreshAccessToken请求令牌):

@Override
public Response intercept(Chain chain) throws IOException {
    Request originalRequest = chain.request();
    Request.Builder requestBuilder = originalRequest.newBuilder();

    String authHeader = "Bearer " + restService.refreshAccessToken();
    requestBuilder.addHeader("Authorization", authHeader);
    return chain.proceed(requestBuilder.build());
}

2 个答案:

答案 0 :(得分:1)

您的Interceptor需要在Interceptor#intercept()方法中注入自己。这样,您可以在没有依赖循环的情况下满足您的Retrofit服务(包括具有添加的拦截器的OkHttpClient)依赖关系。

我的NetworkComponent(提供我的Retrofit服务)存在于我的Application课程中。以下是使用Application Context注入它的示例。

public class AuthInterceptor implements Interceptor {

    @Inject RestService restService;

    public AuthInterceptor(Context context) {
        mContext = context;
    }

    @Override
    public Response intercept(Chain chain) throws IOException {
        // Inject Retrofit service
        ((MyApplication) context.getApplicationContext())
                .getNetworkComponent().inject(this);

        Request originalRequest = chain.request();
        Request.Builder requestBuilder = originalRequest.newBuilder();

        String authHeader = "Bearer " + restService.refreshAccessToken();
        requestBuilder.addHeader("Authorization", authHeader);
        return chain.proceed(requestBuilder.build());
    }
}

您也可以在不注入整个类的情况下设置局部变量,从而可能获得更好的性能。

RestService restService = InjectHelper.getNetworkComponent(mContext).restService();

答案 1 :(得分:0)

我个人更喜欢Lazy注射,这有点清洁

public class AuthInterceptor implements Interceptor {

    Lazy<RestService> restService;

    @Inject
    public AuthInterceptor(Lazy<RestService> restService) {
        this.restService = restService;
    }

    @Override
    public Response intercept(Chain chain) throws IOException {
        Request originalRequest = chain.request();
        Request.Builder requestBuilder = originalRequest.newBuilder();

        String authHeader = "Bearer " + restService.get().refreshAccessToken();
        requestBuilder.addHeader("Authorization", authHeader);
        return chain.proceed(requestBuilder.build());
    }
}