Hilt - @Qualifier

KEH·2023년 3월 3일
1
post-thumbnail

프로젝트를 진행하며 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 개념은 어렵지만 알면 알수록 개발자를 편리하게 만들어주는 최고의 친구인 것 같습니다.
앞으로도 새로운 개념을 알게 되면 꾸준히 기록하는 개발자가 되겠습니다 :)

profile
개발을 즐기고 잘하고 싶은 안드로이드 개발자입니다 :P

0개의 댓글