Making sure that TypedActor use the same instantiation strategy as FromClassCreator

This commit is contained in:
Viktor Klang 2012-06-26 14:09:26 +02:00
parent 32dc65aab5
commit 5f335cb8c8
3 changed files with 27 additions and 10 deletions

View file

@ -10,6 +10,7 @@ import akka.dispatch._
import akka.japi.Creator import akka.japi.Creator
import scala.reflect.ClassTag import scala.reflect.ClassTag
import akka.routing._ import akka.routing._
import akka.util.Reflect
/** /**
* Factory for Props instances. * Factory for Props instances.
@ -188,10 +189,5 @@ case class Props(
* able to optimize serialization. * able to optimize serialization.
*/ */
private[akka] case class FromClassCreator(clazz: Class[_ <: Actor]) extends Function0[Actor] { private[akka] case class FromClassCreator(clazz: Class[_ <: Actor]) extends Function0[Actor] {
def apply(): Actor = try clazz.newInstance catch { def apply(): Actor = Reflect.instantiate(clazz)
case iae: IllegalAccessException
val ctor = clazz.getDeclaredConstructor()
ctor.setAccessible(true)
ctor.newInstance()
}
} }

View file

@ -8,6 +8,7 @@ import language.existentials
import akka.japi.{ Creator, Option JOption } import akka.japi.{ Creator, Option JOption }
import java.lang.reflect.{ InvocationTargetException, Method, InvocationHandler, Proxy } import java.lang.reflect.{ InvocationTargetException, Method, InvocationHandler, Proxy }
import akka.util.{ Timeout, NonFatal, Duration } import akka.util.{ Timeout, NonFatal, Duration }
import akka.util.Reflect.instantiator
import java.util.concurrent.atomic.{ AtomicReference AtomVar } import java.util.concurrent.atomic.{ AtomicReference AtomVar }
import akka.dispatch._ import akka.dispatch._
import java.util.concurrent.TimeoutException import java.util.concurrent.TimeoutException
@ -463,7 +464,7 @@ object TypedProps {
* Scala API * Scala API
*/ */
def apply[T <: AnyRef](interface: Class[_ >: T], implementation: Class[T]): TypedProps[T] = def apply[T <: AnyRef](interface: Class[_ >: T], implementation: Class[T]): TypedProps[T] =
new TypedProps[T](extractInterfaces(interface), () implementation.newInstance()) new TypedProps[T](extractInterfaces(interface), instantiator(implementation))
/** /**
* Uses the supplied thunk as the factory for the TypedActor implementation, * Uses the supplied thunk as the factory for the TypedActor implementation,
@ -507,7 +508,7 @@ case class TypedProps[T <: AnyRef] protected[TypedProps] (
*/ */
def this(implementation: Class[T]) = def this(implementation: Class[T]) =
this(interfaces = TypedProps.extractInterfaces(implementation), this(interfaces = TypedProps.extractInterfaces(implementation),
creator = () implementation.newInstance()) creator = instantiator(implementation))
/** /**
* Uses the supplied Creator as the factory for the TypedActor implementation, * Uses the supplied Creator as the factory for the TypedActor implementation,
@ -519,7 +520,7 @@ case class TypedProps[T <: AnyRef] protected[TypedProps] (
*/ */
def this(interface: Class[_ >: T], implementation: Creator[T]) = def this(interface: Class[_ >: T], implementation: Creator[T]) =
this(interfaces = TypedProps.extractInterfaces(interface), this(interfaces = TypedProps.extractInterfaces(interface),
creator = () implementation.create()) creator = implementation.create _)
/** /**
* Uses the supplied class as the factory for the TypedActor implementation, * Uses the supplied class as the factory for the TypedActor implementation,
@ -531,7 +532,7 @@ case class TypedProps[T <: AnyRef] protected[TypedProps] (
*/ */
def this(interface: Class[_ >: T], implementation: Class[T]) = def this(interface: Class[_ >: T], implementation: Class[T]) =
this(interfaces = TypedProps.extractInterfaces(interface), this(interfaces = TypedProps.extractInterfaces(interface),
creator = () implementation.newInstance()) creator = instantiator(implementation))
/** /**
* Returns a new TypedProps with the specified dispatcher set. * Returns a new TypedProps with the specified dispatcher set.

View file

@ -29,4 +29,24 @@ private[akka] object Reflect {
} }
} }
/**
* INTERNAL API
* @param clazz the class which to instantiate an instance of
* @tparam T the type of the instance that will be created
* @return a new instance from the default constructor of the given class
*/
private[akka] def instantiate[T](clazz: Class[T]): T = try clazz.newInstance catch {
case iae: IllegalAccessException
val ctor = clazz.getDeclaredConstructor()
ctor.setAccessible(true)
ctor.newInstance()
}
/**
* INTERNAL API
* @param clazz the class which to instantiate an instance of
* @tparam T the type of the instance that will be created
* @return a function which when applied will create a new instance from the default constructor of the given class
*/
private[akka] def instantiator[T](clazz: Class[T]): () T = () instantiate(clazz)
} }