【问题标题】:Autowire Subclasses of Generic Class泛型类的 Autowire 子类
【发布时间】:2018-08-27 18:54:39
【问题描述】:

在 Spring Boot 2 中,我尝试使用 Kotlin 创建一系列组件,这些组件都扩展了一个泛型类,但为其提供了特定类型:

abstract class Super<in T: SomeType> {
  abstract fun someMethod(t: T): Boolean
}

// AnotherType and OneMoreType extend SomeType
@Component
class Sub1 : Super<AnotherType> {
  override fun someMethod(t: AnotherType) = true
}

@Component
class Sub2 : Super<OneMoreType> {
  override fun someMethod(t: OneMoreType) = true
}

这一切都编译得很好,但是我想将所有这些都收集起来用于另一个组件:

@Component
class MyService(
  private val subs: List<Super<SomeType>>
)

这会导致no beans 异常。

为了找到这些豆子,我缺少什么?

【问题讨论】:

  • 什么提供​​List&lt;Super&lt;SomeType&gt;&gt;?或者,是否有您期望提供的特定 Spring Boot 机制?
  • 对于普通的beans,如果你做一个某种组件类型的List,Spring会自动获取该类型的所有bean,并自动将它们放入一个列表中。例如,如果我有 3 个 MyClass(或其子类)类型的 bean,并且我尝试自动装配 List&lt;MyClass&gt;,它将包含这 3 个 bean。
  • 这是一个有效的问题。很好奇为什么有人对此投反对票。
  • 我也是。如果我遗漏了一些明显的东西,请告诉我。
  • @samanime,我不知道,谢谢! (我没有投反对票。)

标签: java spring spring-boot generics kotlin


【解决方案1】:

我找到的一个解决方案是接受一个星形投影Super&lt;*&gt;,然后在我访问它时投射它:

@Component
class MyService(
  private val subs: List<Super<*>>
) {
  @Suppress("UNCHECKED_CAST")
  fun getSub(): List<Super<SomeType>>? = subs[0] as List<Super<SomeType>>
}

这可行,但我不喜欢它,因为我必须进行未经检查的演员表。我也无法进行检查演员,因为由于擦除,我无法确定泛型类型(如is Super&lt;SomeType&gt;)。

由于Super 的边界为SomeType,它并不是特别危险,只是丑陋。

建议或更好的解决方案将不胜感激。

【讨论】:

  • 我认为没有比* 更具体的方法,但也许您可以将Super 设为sealed 类,以便您可以限制实现集。
  • 感谢您的建议,但在这种情况下,重点是能够有很多 Super&lt;SomeType&gt; 的实现,然后我对它们都做一些事情。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-11-02
  • 2013-05-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多