Dagger2 生成多个改造拦截器实例
Dagger2 generating multiple instances of retrofit interceptor
尽管 Dagger 2 在 Dagger 模块中将其标记为单例,但 Dagger 2 正在生成多个改装拦截器实例。现在的问题是 AuthorizationInterceptor 构造函数被调用了两次,我不明白为什么,因为我在从登录 API 获取结果后设置的 headers 设置为拦截器的不同实例,而调用其他需要 authorizationToken 的 API 令牌未设置。
这是我的 ApiModule
@Module
open class ApiModule {
@Provides
@Singleton
fun provideHttpLoggingInterceptor(): HttpLoggingInterceptor {
val loggingInterceptor = HttpLoggingInterceptor()
loggingInterceptor.level = HttpLoggingInterceptor.Level.BODY
return loggingInterceptor
}
@Provides
@Singleton
fun provideHeaderInterceptor(): Interceptor {
return AuthorizationInterceptor()
}
@Provides
@Singleton
fun provideHttpClient(interceptor: HttpLoggingInterceptor, headerInterceptor: Interceptor): OkHttpClient {
return OkHttpClient.Builder()
.addInterceptor(interceptor)
.addInterceptor(headerInterceptor)
.build()
}
@Provides
@Singleton
fun provideMoshi(): Moshi {
return Moshi.Builder()
.build()
}
@Provides
@Singleton
fun provideRetrofit(client: OkHttpClient, moshi: Moshi, apiConfig: ApiConfig): Retrofit {
return Retrofit.Builder()
.baseUrl(apiConfig.baseUrl)
.client(client)
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.addConverterFactory(MoshiConverterFactory.create(moshi))
.build()
}
@Provides
@Singleton
fun provideFrappApi(retrofit: Retrofit): FrappApi {
return retrofit.create(FrappApi::class.java)
}
这是我的 AuthorizationInterceptor class
@Singleton
class AuthorizationInterceptor @Inject constructor() : Interceptor {
override fun intercept(chain: Interceptor.Chain?): Response {
val request = chain?.request()
val requestBuilder = request?.newBuilder()
if (request?.header("No-Authorization") == null && authorization.isNotEmpty()) {
requestBuilder?.addHeader("Authorization", authorization)
}
return chain?.proceed(requestBuilder!!.build())!!
}
private var authorization: String = ""
fun setSessionToken(sessionToken: String) {
this.authorization = sessionToken
}
}
如果进行构造函数注入,则无需提供方法。
删除 provideHeaderInterceptor
方法,然后更新 provideHttpClient
方法,如下所示,
@Provides
@Singleton
fun provideHttpClient(interceptor: HttpLoggingInterceptor,
headerInterceptor: AuthorizationInterceptor): OkHttpClient {
return OkHttpClient.Builder()
.addInterceptor(interceptor)
.addInterceptor(headerInterceptor)
.build()
}
或者如果您不喜欢上面的解决方案,您可以删除 AuthorizationInterceptor
class.
中的 @Singleton
和 @Inject
尽管 Dagger 2 在 Dagger 模块中将其标记为单例,但 Dagger 2 正在生成多个改装拦截器实例。现在的问题是 AuthorizationInterceptor 构造函数被调用了两次,我不明白为什么,因为我在从登录 API 获取结果后设置的 headers 设置为拦截器的不同实例,而调用其他需要 authorizationToken 的 API 令牌未设置。
这是我的 ApiModule
@Module
open class ApiModule {
@Provides
@Singleton
fun provideHttpLoggingInterceptor(): HttpLoggingInterceptor {
val loggingInterceptor = HttpLoggingInterceptor()
loggingInterceptor.level = HttpLoggingInterceptor.Level.BODY
return loggingInterceptor
}
@Provides
@Singleton
fun provideHeaderInterceptor(): Interceptor {
return AuthorizationInterceptor()
}
@Provides
@Singleton
fun provideHttpClient(interceptor: HttpLoggingInterceptor, headerInterceptor: Interceptor): OkHttpClient {
return OkHttpClient.Builder()
.addInterceptor(interceptor)
.addInterceptor(headerInterceptor)
.build()
}
@Provides
@Singleton
fun provideMoshi(): Moshi {
return Moshi.Builder()
.build()
}
@Provides
@Singleton
fun provideRetrofit(client: OkHttpClient, moshi: Moshi, apiConfig: ApiConfig): Retrofit {
return Retrofit.Builder()
.baseUrl(apiConfig.baseUrl)
.client(client)
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.addConverterFactory(MoshiConverterFactory.create(moshi))
.build()
}
@Provides
@Singleton
fun provideFrappApi(retrofit: Retrofit): FrappApi {
return retrofit.create(FrappApi::class.java)
}
这是我的 AuthorizationInterceptor class
@Singleton
class AuthorizationInterceptor @Inject constructor() : Interceptor {
override fun intercept(chain: Interceptor.Chain?): Response {
val request = chain?.request()
val requestBuilder = request?.newBuilder()
if (request?.header("No-Authorization") == null && authorization.isNotEmpty()) {
requestBuilder?.addHeader("Authorization", authorization)
}
return chain?.proceed(requestBuilder!!.build())!!
}
private var authorization: String = ""
fun setSessionToken(sessionToken: String) {
this.authorization = sessionToken
}
}
如果进行构造函数注入,则无需提供方法。
删除 provideHeaderInterceptor
方法,然后更新 provideHttpClient
方法,如下所示,
@Provides
@Singleton
fun provideHttpClient(interceptor: HttpLoggingInterceptor,
headerInterceptor: AuthorizationInterceptor): OkHttpClient {
return OkHttpClient.Builder()
.addInterceptor(interceptor)
.addInterceptor(headerInterceptor)
.build()
}
或者如果您不喜欢上面的解决方案,您可以删除 AuthorizationInterceptor
class.
@Singleton
和 @Inject