当前位置: 首页 > 知识库问答 >
问题:

使用Google Guice获取trait的所有实例子类

酆俊远
2023-03-14

我试图得到trait(接口)的所有实例子类。这个特性有多个实现,由第三方用户提供。

这是否可能得到所有实例子类没有显式绑定,因为我没有控制,实现由第三方用户提供。?

我已经看到了同样的问题,你需要明确地绑定。

代码示例:

import javax.inject.Inject

import com.google.inject._

import scala.collection.JavaConversions._


object DemoApp extends App {
  val injector = Guice.createInjector(new AllImplModule)
  injector.getInstance(classOf[Action]).perform()


}

class Action @Inject()(impls: List[B]) {

  def perform() = {
    impls.foreach(b => println(b.name))
  }

}

class AllImplModule extends AbstractModule {
  override def configure() = {
    bind(classOf[Action]).asEagerSingleton()
  }

  @Provides
  @Singleton
  def getAllImpls(injector: Injector): List[B] = {
    injector.getAllBindings().keySet().collect {
      case key: Key[_] if (classOf[B].isAssignableFrom(key.getTypeLiteral().getRawType())) =>
        injector.getInstance(key).asInstanceOf[B]
    }.toList

  }
}

trait B {
  def name: String
}

class C1 extends B {
  override def name: String = "C1"

}


class C2 extends B {
  override def name: String = "C2"
}

这不起作用。任何帮助都将不胜感激!

共有2个答案

华星剑
2023-03-14

您的示例代码看起来不错。下面是一个Scala工作表,它动态查找某个抽象类/特征

import com.google.inject.{AbstractModule, Guice}
import scala.collection.JavaConverters._

trait Foo {
    def name: String
}
class Foo1 extends Foo {
    override def name = "Foo1"
}
class Foo2 extends Foo {
    override def name = "Foo2"
}

val testModule = new AbstractModule {
    override def configure(): Unit = {
        bind(classOf[Foo1]).toInstance(new Foo1)
        bind(classOf[Foo2]).toInstance(new Foo2)
        bind(classOf[Int]).toInstance(42)
    }
}

val injector = Guice.createInjector(testModule)

private def bindingsFor[T](c: Class[T]): Iterable[T] = injector.getAllBindings.asScala.keys
    .filter { key ⇒ c.isAssignableFrom(key.getTypeLiteral.getRawType) }
    .map { key ⇒ injector.getInstance(key).asInstanceOf[T] }

bindingsFor(classOf[Foo]).map(_.name).mkString(", ")

返回:

output: String = Foo1, Foo2
华昕
2023-03-14

可以使用guice multibindings扩展注入trait的多个实现。

添加"com.google.inject.extensions"%"guice-Multibindings"%"4.1.0"到您的build.sbt文件

在Play模块中定义您的绑定如下:

 val multipleBinder = Multibinder.newSetBinder(binder(),classOf[BaseTrait])
 multipleBinder.addBinding().to(classOf[Implementation1])
 multipleBinder.addBinding().to(classOf[Implementation2])

在组件中,当您要注入多个绑定时,请以以下方式声明依赖关系:

baseTraits: java.util.Set[BaseTrait]

那么它应该会起作用。

 类似资料:
  • 我没有问题绑定单例实例到其他一些实例使用@注入。但是,当涉及到绑定一个类的更多实例到其他一些实例(这是单例),它拒绝以某种方式绑定它,我得到了空引用。 我的代码示例是: 当我创建几个WebSocketManagerImpl实例时,每个factoryImpl字段都是空指针。我做错什么了吗?

  • 问题内容: 在Java中,是否有任何可能的方法来获取某个类的所有实例? 问题答案: 实例化类(Singleton模式)时,可以使用Factory静态初始化程序,然后将工厂构造函数中的每个生成的实例添加到List中。 像这样的东西:

  • 问题内容: 我想获取某个类的对象的所有实例。 例如: 应该是或(顺序无关紧要)。 一个加号是,如果该函数将返回具有所请求类的超类的实例,尽管这不是必需的。 我能想到的一种方法是使用包含实例数组的静态类成员变量。在类的构造函数和析构函数中,我将在数组中添加或删除。如果我必须在许多类上这样做,这将很麻烦且容易出错。 问题答案: 如果您从TrackableObject类派生所有对象,则可以将此类设置为处

  • 问题内容: 我有一个函数,该函数接受在whe​​re子句中使用的参数 函数(字符串x)->现在这将创建一个sql查询,该查询将 现在,我希望此函数提供所有行,即等于 当我通过x =“ All”时。 我想创建一个通用查询,当我传递“全部”时,它将返回所有行,否则将过滤我的结果。 问题答案: 只需将where条件排除在外即可。 如果您真的想要它那么复杂的用途 仅过滤空值。

  • 我有一个问题: 多个结构实现一个trait 都可以以相同的方式实现trait 我考虑过写这个(简短版本) 游戏场 这无法编译: 这里怎么了?或者有没有其他方法可以通用地实现此,而不必为和分别键入一次? 谢谢你们

  • 我正在创建一个基于RDFS/OWL的类层次结构,并使用()关系在所有类中创建实例。我想检索一个特定类的实例,不包括它的子类的实例。但是,当我编写SPARQL查询时,它也会给我每个子类的所有实例。 是一个类,它有两个子类:和 换句话说(在某些情况下): 当我查询 感谢任何帮助。多谢了。