Skip to content

Instantly share code, notes, and snippets.

@magro
Created September 30, 2015 10:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save magro/9ad0e607f3c23d1621b9 to your computer and use it in GitHub Desktop.
Save magro/9ad0e607f3c23d1621b9 to your computer and use it in GitHub Desktop.
Scala proxy for lazy values
import java.util.concurrent.atomic.AtomicReference
import scala.reflect.ClassTag
import java.lang.reflect.{Proxy => JProxy, Method, InvocationHandler}
/**
* Creates a proxy for a lazy value, in a project moving to dependency injection this
* was meant to replace legacy stuff where at app start time dependencies were loaded
* too early.
*
* Not sure if this is useful in another context, because `lazy` should be enough in the
* normal world and a runtime DI solution should resolve dependencies on its own...
*/
object Proxy {
def apply[T](provider: => T)(implicit ct: ClassTag[T]): T = {
val clazz = ct.runtimeClass.asInstanceOf[Class[T]]
val handler = new InvocationHandler {
private val proxied = new AtomicReference[T]()
override def invoke(proxy: scala.Any, method: Method, args: Array[AnyRef]): AnyRef = {
if(proxied.get() == null) proxied.set(provider)
method.invoke(proxied.get(), args:_ *)
}
}
JProxy.newProxyInstance(clazz.getClassLoader, Array(clazz), handler).asInstanceOf[T]
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment