【问题标题】:Extending Dropwizard Service class in Clojure在 Clojure 中扩展 Dropwizard 服务类
【发布时间】:2012-01-26 21:48:35
【问题描述】:

我已经使用 Dropwizard 在 Scala 中编写 RESTful API 有一段时间了,我真的很想在 Clojure 中使用它。

我想做的是创建一个com.yammer.dropwizard.Service 的子类,我可以在我的-main 中实例化并运行它,我正在努力实现这一目标。

据我所知,我的选择是:

  1. gen-classns 声明中。不可行,因为我想构建不能在ns 声明中使用的宏(例如defservice)。除非有某种方法可以在运行时生成一个东西并将其传递给 compile,但这似乎是一种肮脏的 hack。
  2. gen-classns 之外。尽管有some code I found,但这似乎根本不起作用。这是一个简单的例子:

    user> (gen-class :name foo :extends Object)
    nil
    user> (foo.)
    Unable to resolve classname: foo
     [Thrown class java.lang.IllegalArgumentException]
    

    我知道gen-class 仅在编译时有效。我把它放到一个文件中并将(foo. 放入我的-main 中,我得到了同样的异常。

  3. proxy。这似乎是最有前途的,它适用于简单的情况,但不适用于扩展 Dropwizard 的 Service 类:

    user> (proxy [Object] [])
    #<Object$0 user.proxy$java.lang.Object$0@249faafc>
    user> (import [com.yammer.dropwizard Service])
    com.yammer.dropwizard.Service
    user> (proxy [Service] ["x"])
    java.lang.Class cannot be cast to java.lang.reflect.ParameterizedType
      [Thrown class java.lang.ClassCastException]
    

    我认为这可能是由于Service 采用了类型参数,但我在 Clojure 中找不到任何有关处理此问题的信息。我的发现似乎表明这些只对 javac 有意义,而被 Clojure 忽略。所以也许我对为什么会发生这种情况是不正确的。

  4. deftype。不起作用,因为Service 是一个类,而deftype 仅适用于接口和协议。

我认为我在正确的轨道上,但我错过了 gen-class 和/或 proxy 工作方式的一些微妙之处,而且 Clojure 文档非常简洁。如何在 Clojure 中扩展这个 Java 类?

【问题讨论】:

  • Clojure 通常可以代理一个接受泛型参数的对象(试试(proxy [java.util.ArrayList] []))。您当前的问题是由于com.yammer.dropwizard.AbstractService 的实现,尤其是在构造函数中对getConfigurationClass 的调用。快速浏览一下,Dropwizard 的类层次结构似乎非常奇怪。

标签: java rest clojure dropwizard


【解决方案1】:

我会说使用选项 1,但除非我误解了您的描述,否则听起来您正在尝试在命名空间表单中编写代码?这不是你想要的。当您将 gen-class 添加到命名空间表单时,将为整个命名空间生成一个 Java 类。然后,您可以通过使用 -prefix 命名 ns 中的函数来覆盖方法(或选择另一个并使用 :method-prefix)。

这是一个例子。我对您用来测试这些类的库知之甚少,但至少应该是相似的:

(ns com.myapp.MyService
  (:gen-class
   :extends com.yammer.dropwizard.Service
   :exposes-methods {someSuperClassMethod someLocalAlias}))

;; now just write your code as normal, note that
;; you can access super-class methods with the exposes-methods
;; map above!

;; prefix your overriden methods with -

(defn -overriddenMethod
  [params]
  ... )

希望有帮助!

【讨论】:

  • 这样做的主要问题是它要求服务的作者将样板文件放入他们的(ns ...)中。我想要的是拥有defservice 生成适当的gen-class(或其他)。如果这是唯一可行的方法,我想这种方法是可以接受的,但它远非我想要的那样。
猜你喜欢
  • 2014-07-13
  • 2015-06-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-27
相关资源
最近更新 更多