我一直在使用Dropwizard在Scala中编写RESTful API一段时间了,我真的很想在Clojure中使用它。
我要做的是创建一个com.yammer.dropwizard.Service
的子类,我可以在我的-main
中实例化并运行,我正在努力实现这一目标。
据我所知,我的选择是:
gen-class
在ns
声明中。不可行,因为我想构建宏(例如defservice
),我无法在ns
声明中使用。除非有某种方法可以在运行时生成一个东西并将其传递给compile
,但这似乎是一个肮脏的黑客。
在gen-class
之外 ns
。尽管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
中,我得到了同样的例外。
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忽略了。所以也许我对于为什么会发生这种情况不正确。
deftype
。不起作用,因为Service
是一个类,deftype
仅适用于接口和协议。
我认为我走在正确的轨道上,但我错过了gen-class
和/或proxy
如何工作的一些细微之处,而且Clojure文档非常简洁。如何在Clojure中扩展此Java类?
答案 0 :(得分:0)
我会说使用选项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]
... )
希望有所帮助!