프로젝트를 진행하며 Hilt 라이브러리를 활용해 DI 환경을 구축했습니다.
그런데 문제가 생겼습니다🥲
@Provides
@Singleton
fun provideOkHttpClient(): OkHttpClient {
return OkHttpClient.Builder()
.readTimeout(30000, TimeUnit.MILLISECONDS)
.connectTimeout(30000, TimeUnit.MILLISECONDS)
.build()
}
@Provides
@Singleton
fun provideInterceptorOkHttpClient(tokenInterceptor: TokenInterceptor): OkHttpClient {
return OkHttpClient.Builder()
.readTimeout(30000, TimeUnit.MILLISECONDS)
.connectTimeout(30000, TimeUnit.MILLISECONDS)
.addInterceptor(tokenInterceptor)
.build()
}
한놈은 TokenInterceptor 가 필요하고, 한놈은 필요가 없는데 똑같은 OkHttpClient 타입이었습니다.
어찌해야하나 이리저리 구글링을 하다보니 @Qualifier
라는 기가막힌 친구가 있었습니다.
@Qualifier
@Retention(AnnotationRetention.BINARY)
annotation class InterceptorOkHttpClient
@Qualifier
@Retention(AnnotationRetention.BINARY)
annotation class NoInterceptorOkHttpClient
@Qualifier
와 @Retention
을 활용하여
1) TokenInterceptor 를 사용하는 OkHttpClient 객체에 대한 어노테이션(InterceptorOkHttpClient)
2) 그렇지 않은 어노테이션(NoInterceptorOkHttpClient)
을 생성합니다.
@NoInterceptorOkHttpClient
@Provides
@Singleton
fun provideOkHttpClient(): OkHttpClient {
return OkHttpClient.Builder()
.readTimeout(30000, TimeUnit.MILLISECONDS)
.connectTimeout(30000, TimeUnit.MILLISECONDS)
.build()
}
@InterceptorOkHttpClient
@Provides
@Singleton
fun provideInterceptorOkHttpClient(tokenInterceptor: TokenInterceptor): OkHttpClient {
return OkHttpClient.Builder()
.readTimeout(30000, TimeUnit.MILLISECONDS)
.connectTimeout(30000, TimeUnit.MILLISECONDS)
.addInterceptor(tokenInterceptor)
.build()
}
이후 좀 전의 코드에 생성한 어노테이션을 추가해줍니다.
이를 통해 위의 OkHttpClient 는 TokenInterceptor 를 사용하지 않는 OkHttpClient 가 되고, 아래는 사용하는 OkHttpClient 로 구분할 수 있게 됩니다.
@NoInterceptorRetrofit
@Provides
@Singleton
fun provideRetrofit(@NoInterceptorOkHttpClient client: OkHttpClient, gson: Gson): Retrofit {
return Retrofit.Builder()
.baseUrl(BuildConfig.BASEURL)
.addConverterFactory(GsonConverterFactory.create(gson))
.client(client)
.build()
}
@InterceptorRetrofit
@Provides
@Singleton
fun provideInterceptorRetrofit(@InterceptorOkHttpClient client: OkHttpClient, gson: Gson): Retrofit {
return Retrofit.Builder()
.baseUrl(BuildConfig.BASEURL)
.addConverterFactory(GsonConverterFactory.create(gson))
.client(client)
.build()
}
Retrofit 객체를 생성할 때 OkHttpClient 를 주입해야 합니다.
이때 각각 파라미터에 @NoInterceptorOkHttpClient
와 @InterceptorOkHttpClient
를 포함하여 OkHttpClient 타입을 선언합니다.
물론 이때도 동일한 Retrofit 타입이 두 가지 버전으로 만들어지므로 @NoInterceptorRetrofit
와 @InterceptorRetrofit
어노테이션을 @Qualifier
, @Retention
을 활용해 생성한 후 선언해줘야 합니다.
https://github.com/FiveSensesApp/FiveSenses-Android/blob/main/app/src/main/java/com/mangpo/taste/di/ApiModule.kt
전체 코드는 위 url 을 통해 확인하실 수 있습니다.
DI 개념은 어렵지만 알면 알수록 개발자를 편리하게 만들어주는 최고의 친구인 것 같습니다.
앞으로도 새로운 개념을 알게 되면 꾸준히 기록하는 개발자가 되겠습니다 :)