文档章节

scala反射生成实例

lost_o0
 lost_o0
发布于 2015/03/02 10:26
字数 650
阅读 1573
收藏 0
点赞 0
评论 0

akka实现的通过反射获取类或生成实例(包含生成`object`实例),但是不能生成抽象类的实例!(这也是为什么继承Actor的业务逻辑类不能是抽象的!)

这些代码可直接摘出来用。

/**
 * Copyright (C) 2009-2014 Typesafe Inc. <http://www.typesafe.com>
 */
package akka.actor

import scala.collection.immutable
import java.lang.reflect.InvocationTargetException
import scala.reflect.ClassTag
import scala.util.Try

/**
 * The DynamicAccess implementation is the class which is used for
 * loading all configurable parts of an actor system (the
 * [[akka.actor.ReflectiveDynamicAccess]] is the default implementation).
 *
 * This is an internal facility and users are not expected to encounter it
 * unless they are extending Akka in ways which go beyond simple Extensions.
 * //这些东西摘出来用嘛。
 */
abstract class DynamicAccess {
  /**
   * Convenience method which given a `Class[_]` object and a constructor description
   * will create a new instance of that class.
   *
   * {{{
   * val obj = DynamicAccess.createInstanceFor(clazz, Seq(classOf[Config] -> config, classOf[String] -> name))
   * }}}
   */
  def createInstanceFor[T: ClassTag](clazz: Class[_], args: immutable.Seq[(Class[_], AnyRef)]): Try[T]

  /**
   * Obtain a `Class[_]` object loaded with the right class loader (i.e. the one
   * returned by `classLoader`).
   */
  def getClassFor[T: ClassTag](fqcn: String): Try[Class[_ <: T]]

  /**
   * Obtain an object conforming to the type T, which is expected to be
   * instantiated from a class designated by the fully-qualified class name
   * given, where the constructor is selected and invoked according to the
   * `args` argument. The exact usage of args depends on which type is requested,
   * see the relevant requesting code for details.
   */
  def createInstanceFor[T: ClassTag](fqcn: String, args: immutable.Seq[(Class[_], AnyRef)]): Try[T]

  /**
   * Obtain the Scala “object” instance for the given fully-qualified class name, if there is one.
   */
  def getObjectFor[T: ClassTag](fqcn: String): Try[T]

  /**
   * This is the class loader to be used in those special cases where the
   * other factory method are not applicable (e.g. when constructing a ClassLoaderBinaryInputStream).
   */
  def classLoader: ClassLoader
}

/**
 * This is the default [[akka.actor.DynamicAccess]] implementation used by [[akka.actor.ExtendedActorSystem]]
 * unless overridden. It uses reflection to turn fully-qualified class names into `Class[_]` objects
 * and creates instances from there using `getDeclaredConstructor()` and invoking that. The class loader
 * to be used for all this is determined by the actor system’s class loader by default.
 */
class ReflectiveDynamicAccess(val classLoader: ClassLoader) extends DynamicAccess {

  override def getClassFor[T: ClassTag](fqcn: String): Try[Class[_ <: T]] =
    Try[Class[_ <: T]]({
      val c = Class.forName(fqcn, false, classLoader).asInstanceOf[Class[_ <: T]]
      val t = implicitly[ClassTag[T]].runtimeClass
      if (t.isAssignableFrom(c)) c else throw new ClassCastException(t + " is not assignable from " + c)
    })

  override def createInstanceFor[T: ClassTag](clazz: Class[_], args: immutable.Seq[(Class[_], AnyRef)]): Try[T] =
    Try {
      val types = args.map(_._1).toArray
      val values = args.map(_._2).toArray
      val constructor = clazz.getDeclaredConstructor(types: _*)
      constructor.setAccessible(true)
      val obj = constructor.newInstance(values: _*)
      val t = implicitly[ClassTag[T]].runtimeClass
      if (t.isInstance(obj)) obj.asInstanceOf[T] else throw new ClassCastException(clazz.getName + " is not a subtype of " + t)
    } recover { case i: InvocationTargetException if i.getTargetException ne null ⇒ throw i.getTargetException }

  override def createInstanceFor[T: ClassTag](fqcn: String, args: immutable.Seq[(Class[_], AnyRef)]): Try[T] =
    getClassFor(fqcn) flatMap { c ⇒ createInstanceFor(c, args) }

  override def getObjectFor[T: ClassTag](fqcn: String): Try[T] = {
    val classTry =
      if (fqcn.endsWith("$")) getClassFor(fqcn)//object命名规则
      else getClassFor(fqcn + "$") recoverWith { case _ ⇒ getClassFor(fqcn) }
    classTry flatMap { c ⇒
      Try {
        val module = c.getDeclaredField("MODULE$")//通过获得变量"MODULE$"来初始化
        module.setAccessible(true)
        val t = implicitly[ClassTag[T]].runtimeClass
        module.get(null) match {
          case null                  ⇒ throw new NullPointerException
          case x if !t.isInstance(x) ⇒ throw new ClassCastException(fqcn + " is not a subtype of " + t)
          case x: T                  ⇒ x
        }
      } recover { case i: InvocationTargetException if i.getTargetException ne null ⇒ throw i.getTargetException }
    }
  }
}


© 著作权归作者所有

共有 人打赏支持
lost_o0
粉丝 10
博文 36
码字总数 31139
作品 0
烟台
Shapeless入门指南(一):自动派生 typeclass 实例

本文由 Jilen 发表在 ScalaCool 团队博客。 shapeless 是一个类型相关的库,提供了很多有趣的功能。 本文介绍其中一个重要功能:自动派生 typeclass 实例。 Hlist Shapeless 实现了 ,不同于...

ScalaCool ⋅ 2017/09/15 ⋅ 0

scala object类与普通class的区别与联系

原讨论:http://stackoverflow.com/questions/1755345/scala-difference-between-object-and-class class是定义是描述。它依照方法、或者其他组成元素定义一个类型。 object是单例。它是你所...

柴火 ⋅ 2014/09/02 ⋅ 0

Scala之TypeTags and Manifests

注:本文为译文,原文是Scala官方文档中的一篇,这里翻译出来作为本系列的一篇文章。原文链接: http://docs.scala-lang.org/overviews/reflection/typetags-manifests.html。 本文原文出处:...

bluishglc ⋅ 2016/09/20 ⋅ 0

Scala "Hello,world!" 程序

"Hello, world!" 程序 首先我们使用标准的 “Hello, world!” 程序来演示一下 Scala 的简单使用 这个程序的结构对于 Java 程序员来说应该比较熟悉: 程序由 main 方法组成, 它使用命令行参数即...

JackieYeah ⋅ 2016/06/25 ⋅ 0

【Scala】Cake模式和依赖注入

依赖注入(Dependency Injection)和控制反转(Inversion of Control) Dependency Injection & Inversion of Control是Martin Fowler在2004年所提出來的一个概念,Martin Fowler在这篇文章中...

JasonDing ⋅ 2016/03/11 ⋅ 0

Scala单例对象和伴生对象

Scala单例对象和伴生对象 Scala 单例对象 转载时请以超链接形式标明文章原始出处和作者信息及本声明 http://www.blogbus.com/dreamhead-logs/58331783.html Singlton是一种为许多人熟知的设计...

秋风醉了 ⋅ 2015/04/10 ⋅ 0

scala写的类,用java的反射机制来获取方法时,在Android不同版本中出现问题。

@肖国颖 你好,想跟你请教个问题: 目前在尝试使用scala编写软件,底层框架使用java写的,使用反射封装了一些事件的方法,上层使用scala写的,其中有一块使用了继承关系,当子类对象反射父类...

was0107 ⋅ 2013/04/08 ⋅ 4

JVM详解之类加载过程

JVM详解之类加载过程 什么叫类?类在什么时候进行加载?类加载过程发生了什么?或者叫jvm做了哪些工作? 类的概念(.java/.class的区别)和范围扩充 java语言和Java虚拟机的概念 java可以运行...

默默学习中 ⋅ 2016/04/15 ⋅ 0

Java反射机制详解上篇

1反射机制是什么 反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的...

xinsz08 ⋅ 2017/07/13 ⋅ 0

Java反射机制

1.反射机制是什么 Reflection(反射)是被视为动态语言的关键,反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法...

ciyo_yang ⋅ 2017/06/26 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

Docker Swarm的前世今生

概述 在我的《Docker Swarm集群初探》一文中,我们实际体验了Docker Swarm容器集群技术的魅力,与《Kubernetes实践录》一文中提到的Kubernetes集群技术相比,Docker Swarm没有Kubernetes显得...

CodeSheep ⋅ 今天 ⋅ 0

骰子游戏代码开源地址

因为阿里云现在服务器已经停用了,所以上面的配置已经失效。 服务端开源地址:https://gitee.com/goalya/chat4.git 客户端开源地址:https://gitee.com/goalya/client4.git 具体运行界面请参考...

算法之名 ⋅ 今天 ⋅ 0

设计模式--装饰者模式

装饰者模式 定义 动态地给一个对象添加一些额外的职责。就增加功能来说,装饰模式相比生成子类更为灵活。 通用类图 意图 动态地给一个对象添加一些额外的职责。就增加功能来说,装饰模式相比...

gaob2001 ⋅ 今天 ⋅ 0

JavaScript零基础入门——(八)JavaScript的数组

JavaScript零基础入门——(八)JavaScript的数组 欢迎大家回到我们的JavaScript零基础入门,上一节课我们讲了有关JavaScript正则表达式的相关知识点,便于大家更好的对字符串进行处理。这一...

JandenMa ⋅ 今天 ⋅ 0

sbt网络问题解决方案

转自:http://dblab.xmu.edu.cn/blog/maven-network-problem/ cd ~/.sbt/launchers/0.13.9unzip -q ./sbt-launch.jar 修改 vi sbt/sbt.boot.properties 增加一个oschina库地址: [reposit......

狐狸老侠 ⋅ 今天 ⋅ 0

大数据,必须掌握的10项顶级安全技术

我们看到越来越多的数据泄漏事故、勒索软件和其他类型的网络攻击,这使得安全成为一个热门话题。 去年,企业IT面临的威胁仍然处于非常高的水平,每天都会看到媒体报道大量数据泄漏事故和攻击...

p柯西 ⋅ 今天 ⋅ 0

Linux下安装配置Hadoop2.7.6

前提 安装jdk 下载 wget http://mirrors.hust.edu.cn/apache/hadoop/common/hadoop-2.7.6/hadoop-2.7.6.tar.gz 解压 配置 vim /etc/profile # 配置java环境变量 export JAVA_HOME=/opt/jdk1......

晨猫 ⋅ 今天 ⋅ 0

crontab工具介绍

crontab crontab 是一个用于设置周期性被执行的任务工具。 周期性执行的任务列表称为Cron Table crontab(选项)(参数) -e:编辑该用户的计时器设置; -l:列出该用户的计时器设置; -r:删除该...

Linux学习笔记 ⋅ 今天 ⋅ 0

深入Java多线程——Java内存模型深入(2)

5. final域的内存语义 5.1 final域的重排序规则 1.对于final域,编译器和处理器要遵守两个重排序规则: (1)在构造函数内对一个final域的写入,与随后把这个被构造对象的引用赋值给一个引用...

江左煤郎 ⋅ 今天 ⋅ 0

面试-正向代理和反向代理

面试-正向代理和反向代理 Nginx 是一个高性能的反向代理服务器,但同时也支持正向代理方式的配置。

秋日芒草 ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部