일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 | 31 |
- 자료형
- 프로그래머스
- 자바
- compose
- Python
- programmers
- 자바리스트정렬
- Dependency
- nullpointerexception방지
- Hilt
- Kotlin
- 문자열
- list
- 백준파이썬
- android
- disposableeffect
- 배열
- 오블완
- 리스트
- 파이썬
- ContentProvider
- 티스토리챌린지
- Java
- 백준
- filternotnull()
- composelifecycle
- jetpack
- 자바set
- 파이썬문법
- Provider
- Today
- Total
study gomi
[Hilt] Hilt의 의존성 그래프 본문
1. 의존성 그래프
- 의존성 주입을 위한 객체 관계를 나타내는 구조
- Hilt가 의존성을 생성하고 주입하는 과정을 시각적으로 이해하도록 도와줌.
cf_ 의존성 그래프란?
의존성 그래프는 객체 간의 의존성을 노드(Node)와 간선(Edge)으로 표현한 구조.
- 노드(Node) : 생성 가능한 객체(클래스나 데이터).
- 간선(Edge): 노드 간의 의존 관계.
예를 들어 ViewModel이 Repository를 필요로 하고, Repository가 Service를 필요로 한다면 그래프는?
ViewModel --> Repository --> Service
2. 생성 원리
- Hilt는 코드에서 @Inject, @Provides, @Binds 등의 주석을 분석하여 의존성 그래프를 생성
cf_ 의존성 그래프 생성 주요 과정
1. 노드 생성
1-1. Inject가 클래스의 생성자에 선언되어 있다면 Hilt는 해당 클래스를 그래프의 노드로 추가
class Repository @Inject constructor(private val service: Service)
- 여기서 Repository는 노드가 됨.
- Service도 노드로 추가
1-2. @Provides 메서드도 노드를 추가
@Module
@InstallIn(SingletonComponent::class)
object AppModule {
@Provides
fun provideService(): Service = ServiceImpl()
}
- 이 경우 Service 타입의 노드가 그래프에 추가 됨.
2. 간선 생성
2-1. 생성자나 함수의 매개변수를 분석하여 의존 관계를 만든다.
class ViewModel @Inject constructor(private val repository: Repository)
- 이 경우 ViewModel 노드는 Repository 노드와 연결 됨.
2-2. 주입된 객체가 또 다른 의존성을 가진다면 그래프는 확장됨.
class Repository @Inject constructor(private val service: Service)
class Service @Inject constructor(private val apiClient: ApiClient)
2-3. 확장된 의존성 그래프의 결과
ViewModel --> Repository --> Service --> ApiClient
3. 의존성 주입의 범위 관리
- Hilt는 의존성의 생명주기를 관리하기 위해 범위(Scope)를 사용.
- 각 범위는 의존성 그래프의 하위 집합을 정의하며 아래와 같은 기본 범위를 제공.
- SingletonComponent: 애플리케이션 전역에서 하나의 인스턴스만 생성.
- ActivityRetainedComponent: ViewModel의 생명주기 동안 유지.
- ActivityComponent: Activity의 생명주기 동안 유지.
- FragmentComponent: Fragment의 생명주기 동안 유지.
@Module
@InstallIn(SingletonComponent::class)
object AppModule {
@Singleton
@Provides
fun provideService(): Service = ServiceImpl()
}
- @Singleton은 Service 객체가 애플리케이션 전체에서 하나의 인스턴스만 유지됨을 보장
4. 의존성 주입 과정
4-1. 의존성 탐색
- Hilt는 객체가 필요한 시점(ViewModel 생성 등)에 의존성을 탐색한다.
class ViewModel @Inject constructor(private val repository: Repository)
- Hilt는 ViewModel이 필요로 하는 Repository를 의존성 그래프에서 찾는다.
4-2. 객체 생성
- 필요한 의존성이 그래프에 없다면 Hilt는 @Inject 또는 @Provides를 통해 객체를 생성
- 예: repository가 Service를 필요로 하면 Service를 먼저 생성하고 Repository를 생성
4-3. 의존성 연결
- 생성된 객체를 연결, 필요로 하는 곳에 주입.
5. 의존성 그래프 예제
5-1. 구성 요소
class ApiClient @Inject constructor()
class Service @Inject constructor(private val apiClient: ApiClient)
class Repository @Inject constructor(private val service: Service)
class ViewModel @Inject constructor(private val repository: Repository)
5-2. 그래프
ViewModel --> Repository --> Service --> ApiClient
- 참고: 그렇다면 그래프의 루트 노드는?? ↓
- 의존성 그래프에서 루트 노드는 특정 클래스(예: ApiClient) 자체가 아니라 의존성을 필요로 하는 시작점.
- 일반적으로 ViewModel이나 그 의존성을 주입받는 컴포넌트(Activity, Fragment 등)이다.
1. 루트 노드의 정의
- 의존성 그래프의 루트 노드는 의존성을 요청하는 출발점.
- Hilt에서 이는 보통 컴포넌트(예: @HiltViewModel, @AndroidEntryPoint로 주석 처리된 Activity/Fragment)다.
- 그래프의 탐색은 이 루트 노드에서 시작해 필요한 의존성을 따라 내려간다.
2. 예제의 구조 좀 더 자세히
class ApiClient @Inject constructor()
class Service @Inject constructor(private val apiClient: ApiClient)
class Repository @Inject constructor(private val service: Service)
@HiltViewModel
class MyViewModel @Inject constructor(private val repository: Repository)
ViewModel --> Repository --> Service --> ApiClient
- 루트 노드: MyViewModel (Hilt가 이 ViewModel을 필요로 할 때 그래프를 탐색 시작).
- MyViewModel은 Repository를 요청.
- Repository는 Service를 요청.
- Service는 ApiClient를 요청
- ViewModel 요청: MyViewModel이 요청되면 Hilt는 ViewModel이 의존하는 Repository를 찾는다.
- Repository 요청: Repository를 생성하기 위해 Service가 필요.
- Service 요청: Service를 생성하기 위해 ApiClient가 필요.
- ApiClient 생성: ApiClient는 의존성이 없으므로 바로 생성.
- 순차 주입: 생성된 객체를 상위 객체에 주입하며 그래프를 완성.
4. 말단(leaf) 노드?
- 여기서는 ApiClient가 의존성 그래프에서의 "말단(leaf) 노드".
- 의존성이 없는 클래스이므로 요청받기 전까지 생성되지 않는다.
- 이 객체는 직접 요청되지 않으며 상위 노드(예: Service)가 요청될 때만 생성됨.
5. 의존성 그래프의 루트는 어디서 결정?
- Hilt에서 루트는 컴포넌트와 연결된다.
- Hilt 컴포넌트(SingletonComponent, ActivityComponent 등)는 특정 생명주기에서 그래프를 관리, 루트 역할을 함.
- Hilt 컴포넌트가 의존성을 필요로 하는 경우 그래프 탐색이 시작됨.
- 예
- @HiltViewModel: ActivityRetainedComponent를 통해 관리되는 ViewModel.
- @AndroidEntryPoint가 있는 Activity/Fragment: 각 컴포넌트가 그래프 탐색의 루트가 됨.
요약
- 루트 노드는 컴포넌트에서 시작됨.
- ApiClient 같은 말단 노드는 의존성의 마지막 지점
- Hilt가 그래프를 탐색하여 필요한 객체를 순차적으로 생성하고 연결5-3. 주입 과정
- ViewModel이 필요할 때 Hilt는 Repository를 확인.
- Repository를 생성하려면 Service가 필요.
- Service를 생성하려면 ApiClient가 필요.
- 최종적으로 모든 객체가 생성되고 연결된다.
6. 장점
- 자동화: 객체 생성과 관리가 자동으로 이루어짐.
- 재사용 가능성: 동일한 객체를 여러 클래스에서 재사용 가능.
- 유지보수 용이: 의존성 관계를 한눈에 파악할 수 있어 코드 유지보수가 쉽다.
'App > Android' 카테고리의 다른 글
Content Provider, Provider? (0) | 2024.11.28 |
---|---|
[Hilt] 의존성 생성 방법 (0) | 2024.11.25 |
Jetpack Compose에서 생명 주기 처리 / LaunchedEffect, SideEffect, DisposalEffect / 설명, 비교 요약 (1) | 2024.11.22 |
[Android/Kotlin] floating button에 직접 그림자 주기 (0) | 2024.10.23 |
[Android/Kotlin] text를 표시하는 floating button (jetpack compose) + button 아래에 하얀색 공백이 보이는 문제 (0) | 2024.10.23 |