【问题标题】:How to effectively use Scala in a Spring MVC project?如何在 Spring MVC 项目中有效地使用 Scala?
【发布时间】:2012-06-28 06:14:35
【问题描述】:

我想创建一个多模块(maven)spring MVC 应用程序,模块如下:

web
persistance (hibernate)
core (general libs)
models
job-server (queue based jobs)
services (business logic)

现在要在这个项目中使用 Scala,我可以在任何地方编写 scala 没有任何问题吗? 还是应该将 scala 用于我的服务模块,而将 java 用于 Web 模块?

我知道hibernate必须在java中。

想法?建议?

有什么问题需要注意吗?这是一个好主意吗?我是否必须破解某些部分才能将它们粘合在一起?

【问题讨论】:

  • 我的建议:“不要”。 ;)

标签: java spring scala maven


【解决方案1】:

是的,您可以在 Spring MVC 代码和 Hibernate 类中使用 Scala。

以下是我的一个项目中使用的 Scala 中的 Spring MVC 控制器示例:

@Controller
class HomeController {
  val log: Logger = LoggerFactory.getLogger(this.getClass.getName)

  @RequestMapping(Array("/"))
  def home: String = {
    log.debug("HomeController::home")

    "home/home"
  }
}

还有一个 Hibernate 域类的例子。注意 Hibernate 的私有 Java 集合类的使用,该类由公共 Scala 集合类为该类的用户改编(由 Scala 的 JavaConversions 类提供帮助)。

@Entity
class Role {
  @Id @GeneratedValue
  var id: Long = _

  @Index(name="role_name")
  var name: String = _

  var created_at: Date = _
  var updated_at: Date = _  

  @ManyToMany
  private var sub_role: java.util.Set[Role] = _
  def subRoles: Set[Role] = {
    if (sub_role == null) sub_role = new java.util.HashSet[Role]
    sub_role
  }

  @ManyToMany
  private var permission: java.util.Set[Permission] = _
  def permissions: Set[Permission] = {
    if (permission == null) permission = new java.util.HashSet[Permission]
    permission
  }
}

我发现我不得不使用 Java 的唯一一件事就是编写 @Retention(RUNTIME) 注释(用于 JSR-303 验证)。

我将 Maven 和 maven-scala-plugin 用于混合 Java/Scala 项目。

【讨论】:

  • 有没有关于如何使用 scala 和 Spring 的手册?是的,我们可以将 Spring 与 scala 一起使用,但是细微差别呢?
  • 您能说得更具体些吗?你会如何在 Scala 中编写 Hibernate 代码?
  • 我不会。具体来说,如果需要使用 Hibernate,我不会选择 Scala。如果这不是必需的,我会放弃 Hibernate。至于 Scala:不要使用 var,不要实例化 java.util 集合,不要使用 JavaConversions,除非你必须(例如,因为你正在调用 Java API),不要显式检查 Scala 代码中的 null 等。您在这里所做的确实是“使用 Hibernate”,但并不是“有效”地使用它——为了使用它,您放弃了所有使 Scala 代码看起来像 Scala 的东西!
  • 我的回答是解决您需要同时使用 Scala 和 Hibernate 的情况。这是许多地方的常规要求。使用 Scala 和 Hibernate 时,您需要使用var,并且您需要使用java.util。你有没有一起使用过 Scala 和 Hibernate?
  • 我当然不想参与一个我们有机会使用 Scala 的项目,但一些狂热者认为,由于 Hibernate 代码不是惯用的 Scala,因此整个项目必须在另一个项目中完成语言。
【解决方案2】:

您可以将 scala 和 java 一起用于您认为最适合的任何事情。

我知道hibernate必须在java中。

这不一定是真的。您可以将 Scala 类用作 Hibernate ORM 对象。您只需要确保编译后的 .class 文件以 Hibernate 期望的相同 getter、setter 和默认构造函数结束。

甚至您的 Web App 模块也可以用 scala 编写。控制器只需要遵守 Spring MVC 所期望的契约即可。

一般来说,几乎所有用 Java 编写的东西都可以用 scala 重写。当然,也有例外,但不要永远限制自己尝试。假设您现有的代码没有做任何疯狂的事情(即黑魔法反射),它应该没问题。

这里有趣的问题是如何让它与 Maven 一起工作......

有一个existing SO question 描述了使用maven-scala-plugin 来使这种项目工作(具有混合scala 和java 资源的多模块)。我将对这个解决方案添加的唯一额外评论是,根据我的经验,我们只能让它与依赖于 java 源的 scala 模块一起工作,而不是相反。这是因为我们的 maven 配置分别使用了 java 编译器和 scala 编译器。理论上,scala 编译器也可以编译 Java 文件,所以如果你将它配置为只使用一个编译器来处理所有事情,你就不会遇到这个限制。

编辑:

布兰克曼评论:
@Jesse 所以你也这样做了?不确定我是否理解 Maven 问题。

是的,我参与了几个使用混合 java 和 scala 源的项目。我们没有将 Scala 用于 Hibernate 层,但我们对其他一切都使用了。

我描述的 maven 问题是我们的 maven-scala-plugin 配置的结果。您必须对其进行配置才能知道如何编译您的 scala 文件。 我们的配置(可能不正确)设置为首先使用 javac 编译 java 文件,然后使用 scalac 编译 scala 文件。这意味着我们不允许编写引用 scala 类的 java 代码,因为它们在编译时不可用。通过正确的配置,应该可以使用 scalac 编译器将所有源代码一起编译,这将消除这个尴尬的限制。我在上面链接的 SO 问题有示例配置以及一些关于我正在谈论的编译时问题的讨论。如果您需要更多关于设置插件的参考,请查看插件的网站(也链接到上面)以获取官方文档。

【讨论】:

  • 在 Hibernate 中使用 Scala 时,您必须记住,您需要使用 java.util 集合类而不是 Scala 集合。
  • @Madoc 谢谢,我想从这些小事中学习谢谢!
  • @Jesse 所以你也这样做了?不确定我是否理解 Maven 问题。
  • @Jesse - 您不一定必须提供 getter 和 setter - JPA 可以直接针对字段。此外,Scala 编译器实际上不能将 .java 编译为 .class 文件,但它确实知道如何根据需要解析 Java,因此它可以理解 Java 源类的结构。
  • @sourcedelica - 是的,你是对的。 javac 编译器很可能仍需要在之后运行,但至少 scalac 编译器不会因为您的 scala 文件引用未编译的 java 类而崩溃。我们(在不知不觉中)做了相反的事情:先编译 java。有关在这方面使用 scalac 的更多信息,即使有一节描述如何在 maven 中工作...codecommit.com/blog/scala/…
猜你喜欢
  • 2016-08-13
  • 2019-04-17
  • 2020-05-10
  • 2023-03-22
  • 2018-09-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多