All Downloads are FREE. Search and download functionalities are using the official Maven repository.

tech.harmonysoft.oss.common.di.CacheableProvider.kt Maven / Gradle / Ivy

package tech.harmonysoft.oss.common.di

import java.util.concurrent.atomic.AtomicReference
import javax.inject.Provider

/**
 * We quite often need to inject not a dependency object itself but a wrapper around it in order to break
 * circular dependency like `A -> B`, `B -> C`, `C -> A`.
 *
 * Many popular dependency injection frameworks like Spring do full context resolve when an actual object needs
 * to be retrieved. The benefit is that is something new is added to context later on, that is properly reflected.
 * The problem is that that is usually such process is slow.
 *
 * When we know that a provider is used as a singleton just to solve circular dependency, it's worth to cache
 * the target decorated object on the first request and reuse it for all subsequent calls. This class facilitates
 * that.
 */
class CacheableProvider(
    private val delegate: () -> T
) : Provider {

    private val targetRef = AtomicReference()

    override fun get(): T {
        val cached = targetRef.get()
        if (cached != null) {
            return cached
        }

        return delegate().apply {
            targetRef.set(this)
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy