Clojure Noir WAR / Servlet的初始化挂钩(CloudFoundry)

时间:2012-02-01 23:51:26

标签: java clojure war leiningen

我正在构建一个Clojure Noir Web应用程序,以便在CloudFoundry中作为WAR文件运行。

在我的project.clj中,我有:

:ring {:handler appname.server/handler}

在server.clj中,我使用Noir创建一个处理程序:

(def handler (noir.server/gen-handler {:ns 'appname}))

我使用lein ring插件构建WAR文件:

lein ring uberwar

然后使用:

推送到CloudFoundry
vmc push appname

请求处理程序正常工作,我可以浏览到应用程序的URL。

所以问题是:启动应用程序时进行初始化的正确方法是什么?

我可以在server.clj中执行以下操作:

(when (System/getenv "VCAP_APPLICATION")
  (init-func))

但是有一些问题。首先,似乎是在错误的时间进行初始化(当读取/评估代码而不是在应用程序启动时)。其次,保护器特定于CloudFoundry,我确定有一个适当的一般WAR方式来做到这一点。

我认为这是ServletContextListener上contextInitialized方法的目的但是如何用Noir / ring挂钩呢?

1 个答案:

答案 0 :(得分:6)

通过查看ring source for WAR handling

来计算出来

project.clj:ring map采用:init关键字,如下所示:

:ring {:init appname.server/my-init
       :handler appname.server/handler}

将在应用程序启动时调用my-init函数。

警告:这显然会增加应用程序初始启动所需的内存量。没有初始化,128M就足够了。使用初始化代码,应用程序启动失败,因此我不得不将内存增加到256M。我怀疑使用init代码时,JVM在编译/执行Clojure代码之前没有时间进行垃圾收集。