源码阅读-SubCut(二)

        现在看下SubCut对类的加载的实现。先看最基本的一个。

private[inject] class ClassInstanceProvider[I <: Any](val clazz: Class[Any]) {
  def newInstance[I](module: BindingModule)(implicit m: scala.reflect.Manifest[I]): I = {
    try {
      clazz.getConstructor(classOf[BindingModule]).newInstance(module).asInstanceOf[I]
    }
    catch {
      case _ : NoSuchMethodException | _ : InstantiationException =>
        try {
          clazz.newInstance.asInstanceOf[I]
        }
        catch {
          case _ : InstantiationException =>
            throw new InstantiationException(("Unable to create injected instance of %s, " +
              "did you provide a zero-arg constructor either with or without implicit binding module?").
              format(clazz.getName))
        }
    }
  }

  override def toString = "ClassInstanceProvider[%s]".format(clazz.getName)
}

  根据源码可看出,通过反射机制先生成构造参数为BindModule或其子类类型的实例,如果没有,则直接反射个无参数的实例,这里就有一个疑问,如果要反射一个类,他的构造参数>0 且不为BindModule时怎么办呢。往下看:

   

private[inject] class NewInstanceProvider[I <: Any](fn: () => I)(implicit m: Manifest[I]) {
  def instance: I = fn()     // create a new instance each time we ask for one
  val boundType = m.erasure.getName

  override def toString = "NewInstanceProvider[%s]".format(boundType)
}

private[inject] class LazyInstanceProvider[I <: Any](fn: () => I) {
  lazy val instance: I = fn()    // create an instance the first time we use it, and always use that

  override def toString = "LazyInstanceProvider[" + instance.toString + "]"
}

  源码中的(fn: () => I)直接可看做 {new Object(args)}。具体的使用则为下面的demo

   

import com.escalatesoft.subcut.inject.NewBindingModule

case class OJS(a: String, b: String)
object Demo2 extends NewBindingModule(module => {
  import module._
  bind[OJS].toProvider {  module => new OJS("1", "2") }
  
})

  类的懒加载主要由Lazy val 去实现,singleton由map集合去实现(如果map中有,则返回,没有则创建)。

  代码解析就到这里了,至于使用上,该项目实现的目标是不用编译即可实现注入,如果你很头痛每次一修改配置Object类,就会编译很长时间的话,值得一试。项目的简介上在2.5版本会支持Json 、xml等格式的加载。至于项目中AutoInjectable,还需要sbt插件,以后如果有机会的话,再说。

   至于注入 trait  A extends B with C{def ....}这种复杂的情况,尚未做测试。

你可能感兴趣的:(源码阅读-SubCut(二))