애플리케이션, 설정 및 모듈
@KoinApplication을 이용한 애플리케이션 부트스트랩
애플리케이션 엔트리 포인트(entry point)를 정의하려면 @KoinApplication을 사용하세요:
@KoinApplication(modules = [MyModule::class])
class MyApp타입 안전한(typed) API를 사용하여 Koin을 시작하세요:
fun main() {
startKoin<MyApp>()
// 또는 설정을 포함하여 시작
startKoin<MyApp> {
printLogger()
}
}사용 가능한 타입 안전 API
| API | 설명 |
|---|---|
startKoin<T>() | Koin을 전역적으로 시작 |
startKoin<T> { } | 설정 블록과 함께 시작 |
koinApplication<T>() | 격리된 KoinApplication 생성 |
koinConfiguration<T>() | 설정 생성 (Compose, Ktor용) |
module<T>() | 단일 @Module 클래스 로드 |
modules(A::class, B::class) | 여러 @Module 클래스 로드 |
개별 모듈 로드하기
@KoinApplication 없이 @Module 클래스를 직접 로드하려면 module<T>() 또는 modules(vararg KClass)를 사용하세요:
startKoin {
module<NetworkModule>()
modules(DataModule::class, CacheModule::class)
}이 방식은 테스트 환경이나 어노테이션 모듈을 DSL 설정과 혼합하여 사용할 때 유용합니다:
// 테스트에서 — 필요한 모듈만 로드
@get:Rule
val koinTestRule = KoinTestRule.create {
module<NetworkModule>()
}INFO
module<T>()와 modules(vararg KClass)는 컴파일러 플러그인이 컴파일 시점에 가로채서 변환하는 스텁(stub) 함수입니다. 이를 사용하려면 Koin 컴파일러 플러그인이 적용되어 있어야 합니다.
@KoinApplication 파라미터
modules: 포함할 모듈 클래스 배열configurations: 로드할 설정 레이블(label) 배열
@KoinApplication(
modules = [CoreModule::class],
configurations = ["production"]
)
class ProdAppINFO
설정이 지정되지 않은 경우, @Configuration(기본 레이블)으로 표시된 모듈이 자동으로 로드됩니다.
모듈 로드 순서 및 오버라이드(Overrides)
Koin은 런타임에 마지막에 로드된 것이 우선(last-wins) 적용됩니다. 즉, 두 모듈이 동일한 타입을 정의할 경우 마지막에 로드된 모듈이 우선권을 가집니다. 컴파일러 플러그인은 @KoinApplication에서 다음과 같은 순서로 모듈 목록을 구성합니다:
- 자동 탐색된(Auto-discovered)
@Configuration모듈 (로컬 + 종속성 JAR) — 먼저 로드됨 - 명시적인
@KoinApplication(modules = [A, B, C])— 선언된 순서대로 마지막에 로드됨
따라서 애플리케이션 레벨의 오버라이드는 항상 종속성 라이브러리의 기본값보다 우선합니다:
// 종속성 라이브러리 모듈 내
@Module @Configuration
class CoreModule {
@Singleton fun feature(): Feature = DefaultFeature()
}
// 애플리케이션 모듈 내
@Module
class AppModule {
@Singleton fun feature(): Feature = AppFeature() // 커스텀 오버라이드
}
@KoinApplication(modules = [AppModule::class])
class MyApp
// 로드 순서: CoreModule (DefaultFeature) → AppModule (AppFeature가 우선함)
// 런타임에 get<Feature>()는 AppFeature를 반환합니다.명시적 목록 내에서는 선언된 순서가 유지됩니다. 따라서 @KoinApplication(modules = [A, B, C])는 A, B, C 순서로 로드되며, 이 셋 중에서는 C가 우선권을 가집니다. 각 항목의 @Module(includes = [...]) 체인은 해당 항목과 함께 그룹화되어 유지됩니다.
만약 어떤 모듈이 명시적 목록에 포함되어 있으면서 @Configuration으로도 탐색되었다면, 해당 모듈은 명시적 위치에서 한 번만 로드됩니다. 따라서 modules = [...]의 선언 순서가 항상 오버라이드 우선순위를 결정합니다.
TIP
여러 @Configuration 모듈 간에 (클래스패스 스캔 순서가 아닌) 특정 로드 순서가 필요한 경우, @KoinApplication(modules = [Core::class, Feature::class, App::class])와 같이 명시적으로 나열하세요. 명시적 목록은 선언 순서를 존중합니다.
@Configuration을 이용한 설정 관리
@Configuration 어노테이션을 사용하면 모듈을 다양한 설정(환경, flavor 등)으로 구성할 수 있습니다. 이는 배포 환경이나 기능 세트별로 모듈을 정리하는 데 유용합니다.
기본적인 설정 사용법
// 모듈을 기본(default) 설정에 배치합니다
@Module
@Configuration
class CoreModuleINFO
기본 설정의 이름은 "default"이며, @Configuration 또는 @Configuration("default")로 사용할 수 있습니다.
설정에서 모듈을 스캔하려면 @KoinApplication을 사용해야 합니다:
// 모듈 A
@Module
@Configuration
class ModuleA
// 모듈 B
@Module
@Configuration
class ModuleB
// 모듈 App, 모든 @Configuration 모듈을 스캔합니다
@KoinApplication
object MyApp다중 설정 지원
하나의 모듈을 여러 설정과 연결할 수 있습니다:
// 이 모듈은 "prod" 및 "test" 설정 모두에서 사용할 수 있습니다
@Module
@Configuration("prod", "test")
class DatabaseModule {
@Single
fun database() = PostgreSQLDatabase()
}
// 이 모듈은 default, test, development에서 사용할 수 있습니다
@Module
@Configuration("default", "test", "development")
class LoggingModule {
@Single
fun logger() = Logger()
}환경별 설정
// 개발 전용 설정
@Module
@Configuration("development")
class DevDatabaseModule {
@Single
fun database() = InMemoryDatabase()
}
// 운영 전용 설정
@Module
@Configuration("production")
class ProdDatabaseModule {
@Single
fun database() = PostgreSQLDatabase()
}
// 여러 환경에서 사용 가능
@Module
@Configuration("default", "production", "development")
class CoreModule {
@Single
fun logger() = Logger()
}@KoinApplication과 함께 설정 사용하기
기본적으로 @KoinApplication은 모든 기본 설정(@Configuration이 태그된 모듈)을 로드합니다.
애플리케이션 부트스트랩에서 이러한 설정을 다음과 같이 참조할 수도 있습니다:
@KoinApplication(configurations = ["default", "production"])
class ProductionApp
@KoinApplication(configurations = ["default", "development"])
class DevelopmentApp
// 기본 설정만 로드 (파라미터가 없는 @KoinApplication과 동일)
@KoinApplication
class SimpleAppINFO
- 빈
@Configuration은@Configuration("default")와 동일합니다. - 특정 설정이 지정되지 않은 경우 "default" 설정이 자동으로 로드됩니다.
- 어노테이션에 목록을 나열하여 모듈을 여러 설정에 속하게 할 수 있습니다.
모듈을 이용한 구성
정의(definitions)는 항상 @Module을 사용하여 명시적인 모듈로 구성하십시오:
@Module을 이용한 클래스 모듈
모듈을 선언하려면 클래스에 @Module 어노테이션을 태그하기만 하면 됩니다:
@Module
class MyModule@KoinApplication에서 모듈을 참조하세요:
@KoinApplication(modules = [MyModule::class])
class MyApp
fun main() {
startKoin<MyApp>()
}@ComponentScan을 이용한 컴포넌트 스캔
어노테이션이 달린 컴포넌트들을 자동으로 탐색하려면 @ComponentScan을 사용하세요:
@Module
@ComponentScan
class MyModule이렇게 하면 현재 패키지와 하위 패키지에서 어노테이션이 달린 컴포넌트들을 스캔합니다. 다음과 같이 패키지를 명시적으로 지정할 수도 있습니다:
@Module
@ComponentScan("com.myapp.features")
class FeatureModuleINFO
@ComponentScan은 동일한 패키지에 대해 모든 Gradle 모듈을 가로질러 탐색합니다.
클래스 모듈 내의 정의
코드 내에서 직접 정의(definition)를 선언하려면, 함수에 정의 어노테이션을 달아주면 됩니다:
// 예시
// class MyComponent(val myDependency : MyDependency)
@Module
class MyModule {
@Single
fun myComponent(myDependency : MyDependency) = MyComponent(myDependency)
}참고:
@InjectedParam(startKoin에서 주입된 파라미터용) 및@Property(프로퍼티 주입용)도 함수 멤버에 사용할 수 있습니다. 이러한 어노테이션에 대한 자세한 내용은 정의(definitions) 문서를 참조하세요.
모듈 포함하기
includes 속성을 사용하여 모듈을 구성(compose)하세요:
@Module
class ModuleA
@Module(includes = [ModuleA::class])
class ModuleB애플리케이션에서 루트(root) 모듈을 참조하세요:
@KoinApplication(modules = [ModuleB::class]) // ModuleA를 자동으로 포함합니다
class MyApp
fun main() {
startKoin<MyApp>()
}