Dagger2 缺点
学习和科普成本极高,API使用非常繁琐。
配置越多,生成的辅助代码越多,会导致:
Koin 优势
开发者需要理解的概念很少,最核心就是理解Scope一个概念,其他看看文档个和源码可以秒懂。
在kotlin语法下(如扩展、委托),API极度简洁、无感、易用。
无反射,无运行时性能损耗。
没有辅助代码生成,纯粹在代码层做配置,所以不会增长编译时间,不会增大APK体积。
Koin基本原理
要注入的对象都定义在Module对象中,一个Module包含多个对象。
Module对象都存储在一个的Scope对象里,一个Scope包含多个Module实例。
所有的Scope都存储在一个Koin对象里,一个Koin包含多个Scope实例。
Koin对象就是一个容器,可以保持一个单例,也可以创建多个Koin实例。
获取要注入的对象,先获取容器,再查找目标Scope,最后调用Scope的get()方法获取对象。
Scope代表作用域,不同作用域下定义两个一样的对象声明,最终会产生不同的对象。
通过Kotlin的委托、扩展、DSL等语法,可以把对象的注入获取封装成简洁、无感知的形式。
其他所有的功能扩展,都是以上面的基本流程展开的,有了主线逻辑,其他都很好懂。
Koin是怎么用的? 看官方文档介绍:
https://insert-koin.io/docs/quickstart/kotlin
要提供的类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 data class HelloMessageData (val message : String = "Hello Koin!" )interface HelloService { fun hello () : String } class HelloServiceImpl (private val helloMessageData: HelloMessageData) : HelloService { override fun hello () = "Hey, ${helloMessageData.message} " }
HelloApplication要通过Koin注入对象。
1 2 3 4 5 6 7 8 9 10 11 12 class HelloApplication : KoinComponent { val helloService by inject<HelloService>() fun sayHello () = println(helloService.hello()) }
在Koin中声明可以注入的对象:
1 2 3 4 val helloModule = module { single { HelloMessageData() } single { HelloServiceImpl(get ()) as HelloService } }
初始化Koin,直接调用代码,自动注入:
1 2 3 4 5 6 7 8 9 10 fun main (vararg args: String ) { startKoin { printLogger() modules(helloModule) } HelloApplication().sayHello() }
Koin项目地址 https://github.com/InsertKoinIO/koin
由于每个版本源码结构变化较大,下面的源码分析基于Koin版本是2.1.6。 即基于commit id 为bbf2b7ca84c3dfda6b1894fc0bfcc7ed0fbc4d89的源码进行分析。
Koin的入口在哪? 首先需要在Application的onCreate()去初始化Koin配置。
1 2 3 4 5 6 startKoin { androidContext(this @MyApplication ) modules(myAppModules) }
最主要的是要声明使用的Module,Module中提供了要注入的对象。
startKoin()做了什么? 先看startKoin()源码,startKoin()代码位于ContextFunctions.kt:
1 2 3 4 5 6 7 8 9 10 11 fun startKoin (koinContext: KoinContext = GlobalContext() , appDeclaration: KoinAppDeclaration): KoinApplication { KoinContextHandler.register(koinContext) val koinApplication = KoinApplication.init () KoinContextHandler.start(koinApplication) appDeclaration(koinApplication) koinApplication.createEagerInstances() return koinApplication }
KoinAppDeclaration是做什么的? KoinAppDeclaration 的定义是:typealias KoinAppDeclaration = KoinApplication.() -> Unit
参数KoinAppDeclaration是一个以KoinApplication为接受者的函数,在函数大括号里调用的方法,如androidContext()、modules()等,都是KoinApplication的成员函数或扩展函数。
KoinContext 是做什么的? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 interface KoinContext { fun get () : Koin fun getOrNull () : Koin? fun setup (koinApplication: KoinApplication ) fun stop () }
根据注释,KoinContext是持有Koin实例的。
startKoin方法中默认实现是GlobalContext,看看GlobalContext的实现:
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 class GlobalContext : KoinContext { private var _koin: Koin? = null override fun get () : Koin = _koin ?: error("KoinApplication has not been started" ) override fun getOrNull () : Koin? = _koin override fun setup (koinApplication: KoinApplication ) = synchronized(this ) { if (_koin != null ) { throw KoinAppAlreadyStartedException("A Koin Application has already been started" ) } _koin = koinApplication.koin } override fun stop () = synchronized(this ) { _koin?.close() _koin = null } }
主要就是存储Koin对象存储为_koin
成员变量。
KoinContextHandler.register(koinContext) 做了什么? KoinContextHandler类也很短,看源码很简单,就是持有KoinContext的对象实例。
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 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 object KoinContextHandler { private var _context: KoinContext? = null private fun getContext () : KoinContext { return _context ?: error("No Koin Context configured. Please use startKoin or koinApplication DSL. " ) } fun get () : Koin = getContext().get () fun getOrNull () : Koin? = _context?.getOrNull() fun register (koinContext: KoinContext ) = synchronized(this ) { if (_context != null ) { error("A KoinContext is already started" ) } _context = koinContext } fun start (koinApplication: KoinApplication ) { getContext().setup(koinApplication) } fun stop () { _context?.stop() _context = null } }
这么设计有什么好处?
可以看到KoinContextHandler是object修饰的,是单例。
我们是可以通过这个单例在任意位置获取到Koin对象的。
具体的应用在KoinComponent:
1 2 3 interface KoinComponent { fun getKoin () : Koin = KoinContextHandler.get () }
只要是实现了KoinComponent接口的类,就可以通过getKoin()获得默认的Koin对象,或者自己提供一个Koin对象也行。
什么时候需要自己提供一个Koin对象?
比如要做Mock测试,可以快速提供一个模拟数据的Koin容器对象,快速做调试。
获取Koin对象有什么用?
这个后面就知道了,因为要注入的对象都在Koin对象里,所以通过Koin对象就可以获取要注入的对象。
KoinApplication.init() 做了什么? 1 2 3 4 5 6 7 8 9 @JvmStatic fun init () : KoinApplication { val app = KoinApplication() app.init () return app }
创建一个KoinApplication 对象,调用其init()方法,然后返回KoinApplication 对象。
KoinApplication的init实例方法做了什么? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 class KoinApplication private constructor () { val koin = Koin() internal fun init () { koin._scopeRegistry.createRootScopeDefinition() } }
KoinApplication 中创建了一个Koin类型的属性。
init()方法调用koin._scopeRegistry.createRootScopeDefinition()
。
Koin._scopeRegistry是干什么的? 1 2 3 4 class Koin { val _scopeRegistry = ScopeRegistry(this ) }
Koin 创建时就创建了ScopeRegistry。
ScopeRegistry顾名思义就是一个Scope花名册,汇总所有Scope的地方。
因为内部有一个Map,Key是Scope的唯一标识,Value是Scope的定义(即ScopeDefinition对象)。
一个Koin对象对应一个ScopeRegistry对象,管理所有Scope。
一个KoinApplication 对象对应一个Koin对象。
ScopeRegistry.createRootScopeDefinition()干了什么? 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 32 33 34 35 class ScopeRegistry (private val _koin: Koin) { private val _scopeDefinitions = HashMap<QualifierValue, ScopeDefinition>() var _rootScopeDefinition: ScopeDefinition? = null internal fun createRootScopeDefinition () { val scopeDefinition = ScopeDefinition.rootDefinition() _scopeDefinitions[ScopeDefinition.ROOT_SCOPE_QUALIFIER.value] = scopeDefinition _rootScopeDefinition = scopeDefinition } } class ScopeDefinition { companion object { const val ROOT_SCOPE_ID = "-Root-" val ROOT_SCOPE_QUALIFIER = _q(ROOT_SCOPE_ID) fun rootDefinition () = ScopeDefinition(ROOT_SCOPE_QUALIFIER, isRoot = true ) }} } fun _q (name: String ) = StringQualifier(name)data class StringQualifier (override val value: QualifierValue) : Qualifier { override fun toString () : String { return value } }
创建了一个ScopeDefinition对象,名字叫-Root-
,
把Root ScopeDefinition存储到 _scopeDefinitions 这个map中。
把Root ScopeDefinition存储到 _rootScopeDefinition 变量中。
也就是把RootScope和普通的Scope分开存储,为什么要分开存储呢?
到后面才知道,因为如果规定对象是在某一个作用域Scope下面,那么这个对象的存储都放在Scope对象里管理,但是没有声明Scope的对象,那么它其实也可以被一个默认的Scope管理,这样代码就统一了,不用多写重复的逻辑,这就是Root Scope。
KoinContextHandler.start(koinApplication)做了什么? 根据上面KoinContextHandler和GlobalContext源码,就是把koinApplication对象里的Koin对象保存在GlobalContext的_koin属性里。
appDeclaration(koinApplication)做了什么? appDeclaration就是调用startKoin方法时传的大括号lambda表达式,koinApplication对象是lambda表达式的接受者。
就是执行大括号内部的逻辑,在上面的例子就是执行:
KoinApplication.androidContext(this@MyApplication)
KoinApplication.modules(myAppModules)
koinApplication.createEagerInstances()做了什么? 结论:
立刻创建Root Scope下在Module中声明了isCreatedAtStart = true的并且要保持单例的对象。
内部调用了Koin的createEagerInstances():
1 2 3 4 5 6 7 8 9 10 internal fun createEagerInstances () { createContextIfNeeded() _scopeRegistry.rootScope.createEagerInstances() } internal fun createContextIfNeeded () { if (_scopeRegistry._rootScope == null ) { _scopeRegistry.createRootScope() } }
ScopeRegistry.createRootScope() 刚开始_scopeRegistry._rootScope是为null的,所以会执行_scopeRegistry.createRootScope():
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 32 internal fun createRootScope () { if (_rootScope == null ) { _rootScope = createScope(ScopeDefinition.ROOT_SCOPE_ID, ScopeDefinition.ROOT_SCOPE_QUALIFIER, null ) } } fun createScope (scopeId: ScopeID , qualifier: Qualifier , source: Any ? = null ) : Scope { if (scopes.contains(scopeId)) { throw ScopeAlreadyCreatedException("Scope with id '$scopeId ' is already created" ) } val scopeDefinition = scopeDefinitions[qualifier.value] return if (scopeDefinition != null ) { val createdScope: Scope = createScope(scopeId, scopeDefinition, source) _scopes[scopeId] = createdScope createdScope } else { throw NoScopeDefFoundException("No Scope Definition found for qualifer '${qualifier.value} '" ) } } private val _scopeDefinitions = HashMap<QualifierValue, ScopeDefinition>()val scopeDefinitions: Map<QualifierValue, ScopeDefinition> get () = _scopeDefinitions private fun createScope (scopeId: ScopeID , scopeDefinition: ScopeDefinition , source: Any ?) : Scope { val scope = Scope(scopeId, scopeDefinition, _koin, source) val links = _rootScope?.let { listOf(it) } ?: emptyList() scope.create(links) return scope }
从ScopeRegistry的_scopeDefinitions这个Map中,取出之前创建过的Root ScopeDefinition对象。
创建Scope对象,把ScopeDefinition对象通过Scope构造函数传入。
调用scope.create(links)
links这里是做什么的暂时不管,因为不是主线。
Scope对象内部逻辑,之后再梳理,会比较连贯,这里先不具体分析。
Scope.createEagerInstances() 1 2 3 4 5 6 7 8 9 internal fun createEagerInstances () { instances.values.filterIsInstance<SingleInstanceFactory<*>>() .filter { instance -> instance.beanDefinition.options.isCreatedAtStart } .forEach { instance -> instance.get ( InstanceContext(_koin, _scope) ) } }
这段代码要到完全解析Scope源码的时候才能看懂。
简单的结论就是: 如果对象声明的时候标记了isCreatedAtStart = true,并且是要求单例,就创建它。
也就是说进可能早的去创建对象,而不是用到时延迟创建。
为什么会有这个需求?
因为可能需要在App启动时触发某些逻辑的运行。
Module Module是如何创建和定义的? 参考官方示例代码 。
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 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 val appModule = module { single<Service> { ServiceImpl() } single<Service>(named("dumb" )) { DumbServiceImpl() } factory { RandomId() } } val mvpModule = module { factory { (id: String) -> FactoryPresenter(id, get ()) } scope<MVPActivity> { scoped { (id: String) -> ScopedPresenter(id, get ()) } } } val mvvmModule = module { viewModel { (id: String) -> SimpleViewModel(id, get ()) } viewModel(named("vm1" )) { (id: String) -> SimpleViewModel(id, get ()) } viewModel(named("vm2" )) { (id: String) -> SimpleViewModel(id, get ()) } scope<MVVMActivity> { scoped { Session() } viewModel { ExtSimpleViewModel(get ()) } viewModel<ExtSimpleViewModel>(named("ext" )) } } val scopeModule = module { scope(named(SCOPE_ID)) { scoped(named(SCOPE_SESSION)) { Session() } onClose { Counter.released++ println("Scoped -SCOPE_SESSION- release = ${Counter.released} " ) } } scope<ScopedActivityA> { scoped { Session() } scoped { SessionActivity(get ()) } } } val dynamicModule = module { single { DynSingle() } scope(named("dynamic_scope" )) { scoped { DynScoped() } } } val javaModule = module { scope<JavaActivity> { scoped { Session() } viewModel { CompatSimpleViewModel(get ()) } } }
module{}是在做什么? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 typealias ModuleDeclaration = Module.() -> Unit fun module (createdAtStart: Boolean = false , override : Boolean = false , moduleDeclaration: ModuleDeclaration ) : Module { val module = Module(createdAtStart, override ) moduleDeclaration(module) return module }
创建了一个Module对象,然后执行moduleDeclaration函数,返回创建的Module对象。
moduleDeclaration函数也就是module{}大括号里的逻辑,大括号里的方法调用都委托给了Module对象。
所以分析module{}大括号里的逻辑,也就是主要分析Module中各个方法的逻辑。
从上面的示例中,可以看到调用的Module方法有:
factory
single
scope
viewModel
接下来一个个分析。
Module类定义 Module类定义代码很短,直接贴出来:
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 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 class Module ( val createAtStart: Boolean , val override : Boolean ) { val rootScope: ScopeDefinition = ScopeDefinition.rootDefinition() var isLoaded: Boolean = false internal set val otherScopes = arrayListOf<ScopeDefinition>() fun scope (qualifier: Qualifier , scopeSet: ScopeDSL .() -> Unit ) { val scopeDefinition = ScopeDefinition(qualifier) ScopeDSL(scopeDefinition).apply(scopeSet) otherScopes.add(scopeDefinition) } inline fun <reified T> scope (scopeSet: ScopeDSL .() -> Unit ) { val scopeDefinition = ScopeDefinition(TypeQualifier(T::class )) ScopeDSL(scopeDefinition).apply(scopeSet) otherScopes.add(scopeDefinition) } inline fun <reified T> single ( qualifier: Qualifier ? = null , createdAtStart: Boolean = false , override : Boolean = false , noinline definition: Definition <T > ) : BeanDefinition<T> { return Definitions.saveSingle( qualifier, definition, rootScope, makeOptions(override , createdAtStart) ) } fun makeOptions (override : Boolean , createdAtStart: Boolean = false ) : Options = Options(this .createAtStart || createdAtStart, this .override || override ) inline fun <reified T> factory ( qualifier: Qualifier ? = null , override : Boolean = false , noinline definition: Definition <T > ) : BeanDefinition<T> { return Definitions.saveFactory(qualifier, definition, rootScope, makeOptions(override )) } operator fun plus (module: Module ) = listOf(this , module) operator fun plus (modules: List <Module >) = listOf(this ) + modules } operator fun List<Module> .plus (module: Module ) : List<Module> = this + listOf(module)typealias Definition<T> = Scope.(DefinitionParameters) -> T
Module.factory()在做什么? 1 2 3 4 5 6 7 inline fun <reified T> factory ( qualifier: Qualifier ? = null , override : Boolean = false , noinline definition: Definition <T > ) : BeanDefinition<T> { return Definitions.saveFactory(qualifier, definition, rootScope, makeOptions(override )) }
Definitions.saveFactory()源码:
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 inline fun <reified T> saveFactory ( qualifier: Qualifier ? = null , noinline definition: Definition <T >, scopeDefinition: ScopeDefinition , options: Options ) : BeanDefinition<T> { val beanDefinition = createFactory(qualifier, definition, scopeDefinition, options) scopeDefinition.save(beanDefinition) return beanDefinition } inline fun <reified T> createFactory ( qualifier: Qualifier ? = null , noinline definition: Definition <T >, scopeDefinition: ScopeDefinition , options: Options , secondaryTypes: List <KClass <*>> = emptyList() ): BeanDefinition<T> { return BeanDefinition( scopeDefinition, T::class , qualifier , definition , Kind.Factory , options = options , secondaryTypes = secondaryTypes ) }
这里注意factory()最后一个参数definition是一个lambda表达式,代表创建对象的函数,执行这个函数,就会创建对象并获得它。
definition最终被存储到BeanDefinition中,名字很形象,这里把要注入的对象都叫做Bean。
接下来的关键逻辑在scopeDefinition.save(beanDefinition)
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 class ScopeDefinition (val qualifier: Qualifier, val isRoot: Boolean = false , private val _definitions: HashSet<BeanDefinition<*>> = hashSetOf()) { val definitions: Set<BeanDefinition<*>> get () = _definitions fun save (beanDefinition: BeanDefinition <*>, forceOverride: Boolean = false ) { if (definitions.contains(beanDefinition)) { if (beanDefinition.options.override || forceOverride) { _definitions.remove(beanDefinition) } else { val current = definitions.firstOrNull { it == beanDefinition } throw DefinitionOverrideException("Definition '$beanDefinition ' try to override existing definition. Please use override option or check for definition '$current '" ) } } _definitions.add(beanDefinition) } }
根据Module的源码,这里的scopeDefinition是rootScope,并且rootScope是在Module创建时一同创建的。
这里会有一个疑问,之前在Koin的ScopeRegistry里也创建了一个rootScope,root Scope有两个不同的实例,会不会有问题?看后面的逻辑就知道是没有问题的。
scopeDefinition.save(beanDefinition)做的就是把beanDefinition存储到到ScopeDefinition的Set类型属性中。
也就是说一个ScopeDefinition对应多个BeanDefinition。
Module.single()在做什么? Module.single():
1 2 3 4 5 6 7 8 9 10 11 12 13 inline fun <reified T> single ( qualifier: Qualifier ? = null , createdAtStart: Boolean = false , override : Boolean = false , noinline definition: Definition <T > ) : BeanDefinition<T> { return Definitions.saveSingle( qualifier, definition, rootScope, makeOptions(override , createdAtStart) ) }
Definitions.saveSingle():
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 object Definitions { inline fun <reified T> saveSingle ( qualifier: Qualifier ? = null , noinline definition: Definition <T >, scopeDefinition: ScopeDefinition , options: Options ) : BeanDefinition<T> { val beanDefinition = createSingle(qualifier, definition, scopeDefinition, options) scopeDefinition.save(beanDefinition) return beanDefinition } inline fun <reified T> createSingle ( qualifier: Qualifier ? = null , noinline definition: Definition <T >, scopeDefinition: ScopeDefinition , options: Options , secondaryTypes: List <KClass <*>> = emptyList() ): BeanDefinition<T> { return BeanDefinition( scopeDefinition, T::class , qualifier , definition , Kind.Single , options = options , secondaryTypes = secondaryTypes ) } }
createSingle()与createFactory()创建BeanDefinition的区别在于,前者给BeanDefinition构造函数传的是Kind.Single,后者传的是Kind.Factory。
具体有什么用,得看使用BeanDefinition的地方。
scopeDefinition.save(beanDefinition)的过程与factory()是一样的,把beanDefinition存储在scopeDefinition的Set属性中。
Module.scope()在做什么? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 fun scope (qualifier: Qualifier , scopeSet: ScopeDSL .() -> Unit ) { val scopeDefinition = ScopeDefinition(qualifier) ScopeDSL(scopeDefinition).apply(scopeSet) otherScopes.add(scopeDefinition) } inline fun <reified T> scope (scopeSet: ScopeDSL .() -> Unit ) { val scopeDefinition = ScopeDefinition(TypeQualifier(T::class )) ScopeDSL(scopeDefinition).apply(scopeSet) otherScopes.add(scopeDefinition) }
创建ScopeDefinition对象,传递ScopeDefinition的唯一标识。
创建ScopeDSL对象,执行scopeSet这个lambda表达式,lambda表达式中可以不带前缀的调用ScopeDSL中的方法。
新建的ScopeDefinition存储到Module的otherScopes这个list中。
ScopeDSL里有哪些方法可以调用? 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 32 33 34 35 36 37 38 39 class ScopeDSL (val scopeDefinition: ScopeDefinition) { @Deprecated("Can't use Single in a scope. Use Scoped instead" , level = DeprecationLevel.ERROR) inline fun <reified T> single ( qualifier: Qualifier ? = null , override : Boolean = false , noinline definition: Definition <T > ) : BeanDefinition<T> { error("Scoped definition is deprecated and has been replaced with Single scope definitions" ) } inline fun <reified T> scoped ( qualifier: Qualifier ? = null , override : Boolean = false , noinline definition: Definition <T > ) : BeanDefinition<T> { return Definitions.saveSingle( qualifier, definition, scopeDefinition, Options(isCreatedAtStart = false , override = override ) ) } inline fun <reified T> factory ( qualifier: Qualifier ? = null , override : Boolean = false , noinline definition: Definition <T > ) : BeanDefinition<T> { return Definitions.saveFactory( qualifier, definition, scopeDefinition, Options(isCreatedAtStart = false , override = override ) ) } }
ScopeDSL里的scoped()方法跟Module.single()方法调用逻辑一样,factory()方法跟Module.factory()方法一样。
区别在于ScopeDSL中ScopeDefinition不是Root Scope,是刚才在Module.scope()里创建的ScopeDefinition。
Module.viewModel()在哪定义的?做了什么? 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 inline fun <reified T : ViewModel> Module.viewModel ( qualifier: Qualifier ? = null , override : Boolean = false , noinline definition: Definition <T > ) : BeanDefinition<T> { val beanDefinition = factory(qualifier, override , definition) beanDefinition.setIsViewModel() return beanDefinition } const val ATTRIBUTE_VIEW_MODEL = "isViewModel" fun BeanDefinition<*> .setIsViewModel () { properties[ATTRIBUTE_VIEW_MODEL] = true } fun BeanDefinition<*> .isViewModel () : Boolean { return properties.getOrNull(ATTRIBUTE_VIEW_MODEL) ?: false }
还是调用了factory()。
额外给BeanDefinition的properties加了一个isViewModel的属性,方便判断是不是ViewModel的BeanDefinition,其他没有什么影响。
Module总结
在module中声明的对象不会立刻创建,创建对象的函数会当做BeanDefinition类型的变量存储在ScopeDefinition里Set属性中,以供需要时运行来创建对象。
scoped{}下声明的对象,存储在Module的otherScopes列表中。
没有在scoped{}下声明的对象,存储在Module的rootScope中。
Koin怎么加载声明的Module的? KoinApplication.modules() 在startKoin的lambda表达式里,通过调用KoinApplication.modules()加载指定的Module对象。
KoinApplication.modules()源码:
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 fun modules (modules: List <Module >) : KoinApplication { if (koin._logger.isAt(Level.INFO)) { val duration = measureDuration { loadModules(modules) } val count = koin._scopeRegistry.size() koin._logger.info("loaded $count definitions - $duration ms" ) } else { loadModules(modules) } if (koin._logger.isAt(Level.INFO)) { val duration = measureDuration { koin.createRootScope() } koin._logger.info("create context - $duration ms" ) } else { koin.createRootScope() } return this } private fun loadModules (modules: List <Module >) { koin.loadModules(modules) }
核心逻辑是koin.loadModules(modules)。
Koin.loadModules(modules) 1 2 3 4 5 6 7 8 9 10 class Koin { val _modules = hashSetOf<Module>() fun loadModules (modules: List <Module >) = synchronized(this ) { _modules.addAll(modules) _scopeRegistry.loadModules(modules) } }
ScopeRegistry.loadModules(modules) scopeRegistry.loadModules(modules)源码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 internal fun loadModules (modules: Iterable <Module >) { modules.forEach { module -> if (!module.isLoaded) { loadModule(module) module.isLoaded = true } else { _koin._logger.error("module '$module ' already loaded!" ) } } } private fun loadModule (module: Module ) { declareScope(module.rootScope) declareScopes(module.otherScopes) } private fun declareScopes (list: List <ScopeDefinition >) { list.forEach { scopeDefinition -> declareScope(scopeDefinition) } }
每个Module中所有的ScopeDefinition都会调用declareScope()。
ScopeRegistry.declareScope(modules) 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 private val _scopeDefinitions = HashMap<QualifierValue, ScopeDefinition>() val scopeDefinitions: Map<QualifierValue, ScopeDefinition> get () = _scopeDefinitions private val _scopes = HashMap<ScopeID, Scope>()private fun declareScope (scopeDefinition: ScopeDefinition ) { declareDefinitions(scopeDefinition) declareInstances(scopeDefinition) } private fun declareInstances (scopeDefinition: ScopeDefinition ) { _scopes.values.filter { it._scopeDefinition == scopeDefinition }.forEach { it.loadDefinitions(scopeDefinition) } } private fun declareDefinitions (definition: ScopeDefinition ) { if (scopeDefinitions.contains(definition.qualifier.value)) { mergeDefinitions(definition) } else { _scopeDefinitions[definition.qualifier.value] = definition.copy() } } private fun mergeDefinitions (definition: ScopeDefinition ) { val existing = scopeDefinitions[definition.qualifier.value] ?: error("Scope definition '$definition ' not found in $_scopeDefinitions " ) definition.definitions.forEach { existing.save(it) } }
ScopeRegistry.declareDefinitions() declareDefinitions()做的是:
如果发现ScopeRegistry的scopeDefinitions有Module中的ScopeDefinition,调用mergeDefinitions做两个ScopeDefinition的合并。
怎么合并?就是把Module里的ScopeDefinition里的Set属性全部取出来,添加到ScopeRegistry中已存在的ScopeDefinition的Set属性中,Set属性存储的都是BeanDefinition。
如果ScopeRegistry的scopeDefinitions没有Module中的ScopeDefinition,就直接存储到ScopeRegistry的_scopeDefinition哈希表中。
ScopeRegistry.declareInstances() declareInstances()做的是:
在ScopeRegistry的_scopes里寻找有没有Module中定义的Scope,有的话调用Scope的loadDefinitions()方法。
Scope.loadDefinitions() 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 data class Scope ( val id: ScopeID, val _scopeDefinition: ScopeDefinition, val _koin: Koin, val _source: Any? = null ) { val _linkedScope: ArrayList<Scope> = arrayListOf() val _instanceRegistry = InstanceRegistry(_koin, this ) fun loadDefinitions (scopeDefinition: ScopeDefinition ) { scopeDefinition.definitions.forEach { _instanceRegistry.createDefinition(it) } } }
ScopeDefinition的definitions属性类型是Set<BeanDefinition<*>>
。
InstanceRegistry.createDefinition(BeanDefinition) 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 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 class InstanceRegistry (val _koin: Koin, val _scope: Scope) { private val _instances = HashMap<IndexKey, InstanceFactory<*>>() val instances: Map<IndexKey, InstanceFactory<*>> get () = _instances internal fun createDefinition (definition: BeanDefinition <*>) { saveDefinition(definition, false ) } fun saveDefinition (definition: BeanDefinition <*>, override : Boolean ) { val defOverride = definition.options.override || override val instanceFactory = createInstanceFactory(_koin, definition) saveInstance( indexKey(definition.primaryType, definition.qualifier), instanceFactory, defOverride ) definition.secondaryTypes.forEach { clazz -> if (defOverride) { saveInstance( indexKey(clazz, definition.qualifier), instanceFactory, defOverride ) } else { saveInstanceIfPossible( indexKey(clazz, definition.qualifier), instanceFactory ) } } } private fun createInstanceFactory ( _koin: Koin , definition: BeanDefinition <*> ) : InstanceFactory<*> { return when (definition.kind) { Kind.Single -> SingleInstanceFactory(_koin, definition) Kind.Factory -> FactoryInstanceFactory(_koin, definition) } } private fun saveInstance (key: IndexKey , factory: InstanceFactory <*>, override : Boolean ) { if (_instances.contains(key) && !override ) { error("InstanceRegistry already contains index '$key '" ) } else { _instances[key] = factory } } }
这里做的主要是两件事:
根据BeanDefinition的Kind属性,决定创建SingleInstanceFactory还是FactoryInstanceFactory。
也就是说之前在module{}里配置时用到了factory{}就会创建FactoryInstanceFactory,用到single{}就会创建SingleInstanceFactory。
InstanceFactory对象保存在InstanceRegistry的_instances哈希表中。
InstanceRegistry是Scope的属性。
FactoryInstanceFactory是什么? 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 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 class FactoryInstanceFactory <T > (koin: Koin, beanDefinition: BeanDefinition<T>) : InstanceFactory<T>(koin, beanDefinition) { override fun isCreated () : Boolean = false override fun drop () { beanDefinition.callbacks.onClose?.invoke(null ) } override fun get (context: InstanceContext ) : T { return create(context) } } abstract class InstanceFactory <T > (private val _koin: Koin, val beanDefinition: BeanDefinition<T>) { abstract fun get (context: InstanceContext ) : T open fun create (context: InstanceContext ) : T { if (_koin._logger.isAt(Level.DEBUG)) { _koin._logger.debug("| create instance for $beanDefinition " ) } try { val parameters: DefinitionParameters = context.parameters return beanDefinition.definition.invoke( context.scope, parameters ) } catch (e: Exception) { val stack = e.toString() + ERROR_SEPARATOR + e.stackTrace.takeWhile { !it.className.contains("sun.reflect" ) } .joinToString(ERROR_SEPARATOR) _koin._logger.error("Instance creation error : could not create instance for $beanDefinition : $stack " ) throw InstanceCreationException("Could not create instance for $beanDefinition " , e) } } abstract fun isCreated () : Boolean abstract fun drop () companion object { const val ERROR_SEPARATOR = "\n\t" } }
InstanceFactory类核心就是create()方法,会调用BeanDefinition里definition属性函数来创建对象,并传递正确的参数。
FactoryInstanceFactory的核心是get()方法,get()是对外提供对象的,每次get()都会create()新的对象。
SingleInstanceFactory是什么? 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 32 class SingleInstanceFactory <T > (koin: Koin, beanDefinition: BeanDefinition<T>) : InstanceFactory<T>(koin, beanDefinition) { private var value: T? = null override fun isCreated () : Boolean = (value != null ) override fun drop () { beanDefinition.callbacks.onClose?.invoke(value) value = null } override fun create (context: InstanceContext ) : T { return synchronized(this ) { if (value == null ) { super .create(context) } else value ?: error("Single instance created couldn't return value" ) } } @Suppress("UNCHECKED_CAST" ) override fun get (context: InstanceContext ) : T { if (!isCreated()) { value = create(context) } return value ?: error("Single instance created couldn't return value" ) } }
第一次get()时,会create()新对象,并缓存在value属性中。
后续get()都会读取缓存的value。
也就是说一旦get()过一次,对象就会一直保存在Scope对象里面,Scope对象就是管理要注入的对象的。
InstanceFactory.get()什么时候调用? 调用链:
Scope.get() -> Scope.resolveInstance() -> InstanceRegistry.resolveInstance() -> InstanceFactory.get()
加载Module总结 加载Module主要是做了:
把module{}中声明的BeanDefinition全部复制到Koin里的ScopeRegistry里已有的ScopeDefinition里。这样不同地方的声明的对象创建过程就都汇总到同一个ScopeDefinition里了,可以集中式管理。
如果module{}中声明的Scope对象已经存在,把InstanceFactory创建好,存储在Scope的_instanceRegistry的属性中的_instances哈希表属性中,Scope管理对象的创建。
怎么从Koin中获取注入的对象? 示例代码:
1 2 3 4 class HelloApplication : KoinComponent { val helloService by inject<HelloService>() }
KoinComponent.inject():
1 2 3 4 5 inline fun <reified T> KoinComponent.inject ( qualifier: Qualifier ? = null , noinline parameters: ParametersDefinition ? = null ) : Lazy<T> = lazy(LazyThreadSafetyMode.NONE) { getKoin().get <T>(qualifier, parameters) }
Koin.get():
1 2 3 4 inline fun <reified T> get ( qualifier: Qualifier ? = null , noinline parameters: ParametersDefinition ? = null ) : T = _scopeRegistry.rootScope.get (qualifier, parameters)
最终还是调用了Root Scope的get()方法来获取对象。
Scope.get()做了什么? 调用链:Scope.get() -> Scope.resolveInstance() -> InstanceRegistry.resolveInstance() -> InstanceFactory.get()
InstanceFactory如果是FactoryInstanceFactory,每次get()会创建新的对象。
InstanceFactory如果是SingleInstanceFactory,每次get()会获得同一个对象。
怎么获取特定的Scope? 在module里把对象声明在特定的Scope下。
那么想要获取Scope下的对象,就得调用Scope的get()方法。那么首先就得获得Scope对象。
可以通过Koin对象中的getOrCreateScope()来获取Scope。
内部实现:
1 2 3 4 5 6 7 8 9 10 11 12 fun getOrCreateScope (scopeId: ScopeID , qualifier: Qualifier ) : Scope { return _scopeRegistry.getScopeOrNull(scopeId) ?: createScope(scopeId, qualifier) } fun createScope (scopeId: ScopeID , qualifier: Qualifier , source: Any ? = null ) : Scope { if (_logger.isAt(Level.DEBUG)) { _logger.debug("!- create scope - id:'$scopeId ' q:$qualifier " ) } return _scopeRegistry.createScope(scopeId, qualifier, source) }
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 typealias ScopeID = Stringprivate val _scopes = HashMap<ScopeID, Scope>()fun createScope (scopeId: ScopeID , qualifier: Qualifier , source: Any ? = null ) : Scope { if (scopes.contains(scopeId)) { throw ScopeAlreadyCreatedException("Scope with id '$scopeId ' is already created" ) } val scopeDefinition = scopeDefinitions[qualifier.value] return if (scopeDefinition != null ) { val createdScope: Scope = createScope(scopeId, scopeDefinition, source) _scopes[scopeId] = createdScope createdScope } else { throw NoScopeDefFoundException("No Scope Definition found for qualifer '${qualifier.value} '" ) } } private fun createScope (scopeId: ScopeID , scopeDefinition: ScopeDefinition , source: Any ?) : Scope { val scope = Scope(scopeId, scopeDefinition, _koin, source) val links = _rootScope?.let { listOf(it) } ?: emptyList() scope.create(links) return scope }
Scope是怎么唯一标识的? 通过ScopeID唯一标识,ScopeID是String的别名。
因为ScopeRegistry的_scopes哈希表存储Scope是以ScopeID为Key。
qualifier是唯一标识ScopeDefinition的,两者不要搞混。
在Module.scope()声明scope时传的名字参数,传的也是qualifier,决定的是ScopeDefinition的唯一性。
module中可以有多个相同名称的scope声明 也就是说如果在module中定义多个qualifier一样的scope:
1 2 3 4 5 6 7 8 module { scope(named("Hello" )) { factory { String("Luffy" ) } } scope(named("Hello" )) { factory { String("Luffy" ) } } }
根据上面的源码看,scope{}内部的BeanDefinition最终都是合并到同一个ScopeDefinition中的,也就是Koin里的ScopeRegistry里的存储ScopeDefinition的哈希表中的ScopeDefinition。
两个不同的Scope可以对应同一个ScopeDefinition 还可以发现,可以有两个不同的Scope,对应同一个ScopeDefinition,但实际内部对象创建还是两份的。
如何清空Scope里的对象? 为什么要清空呢?
比如有一个用户登录的作用域,不同用户登录,用户信息是不一样的,需要在用户注销后清空之前已创立的用户Scope。
调用Scope.close()即可:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 fun close () = synchronized(this ) { clear() _koin._scopeRegistry.deleteScope(this ) } internal fun clear () = synchronized(this ) { _closed = true if (_koin._logger.isAt(Level.DEBUG)) { _koin._logger.info("closing scope:'$id '" ) } _callbacks.forEach { it.onScopeClose(this ) } _callbacks.clear() _instanceRegistry.close() }
ScopeRegistry.deleteScope():
1 2 3 4 5 private val _scopes = HashMap<ScopeID, Scope>() fun deleteScope (scope: Scope ) { _scopes.remove(scope.id) }
把创建的Scope清除,因为Scope中缓存着创建的对象。
InstanceRegistry.close():
1 2 3 4 internal fun close () { _instances.values.forEach { it.drop() } _instances.clear() }
对于FactoryInstanceFactory的drop(),没做什么。
对于SingleInstanceFactory的drop(),会把缓存的value变量置为null。
Koin总结 Koin主要是围绕Scope构建的对象创建和存储体系,结构层次非常简洁清晰。
剩下未分析的特性,在上面的基本框架明确的情况下,稍微看看源码很容易就能懂,包括:
启动时创建对象(createAtStart)
定义覆盖(override)
secondaryTypes
properties
callback
android扩展包
参考资料