如何在Clojure应用程序中使用Spring Beans?

时间:2013-06-05 01:58:50

标签: java spring clojure

我有很多spring bean可以封装现有的业务逻辑。现在我希望在我的新Clojure Compojure应用程序中重用那些Spring Beans。我该怎么做?

我正在寻找的是Clojure相当于此

Context context = new ClassPathXmlApplicationContext(....);

MyBean mybean = context.get("mybean", MyBean.class)

有没有Clojure这样做的方式?

2 个答案:

答案 0 :(得分:6)

(let [context (ClassPathXmlApplicationContext. ...)
      mybean  (.get context "mybean" MyBean)]
  ...)

是您的Java代码的Clojure等价物。 ...是您接下来想做的事情。或者如果你想返回mybean作为整个事物的价值(也许这将包含在一个函数中):

(let [context (ClassPathXmlApplicationContext. ...)]
  (.get context "mybean" MyBean))

注意ClassPathXmlApplicationContext.末尾的点;这是new的简写,如(new ClassPathXmlApplicationContext ...)

答案 1 :(得分:5)

我一直在使用Spring和Clojure一段时间了。我必须承认越来越少地使用它,因为Spring在Clojure世界中并不是必需的。我发现它有用的是测试我的Spring配置和运行bean。首先我如何使用我的代码,然后是代码本身。

用法

(&init "applicationContext.xml")
(with-spring [mybean myotherbean]
    (.method mybean arg1 arg2 arg3)
    (.method myotherbean arg))

&init读取Spring应用程序上下文并将其填充到var中。 with-spring为向量中的每个名称调用getBean,使用let将其分配给同名的“变量”。然后使用这些作业执行正文。

这是实现它的代码

(declare ^:dynamic *spring-context*)

(defn load-context 
  "Load a Spring Framwork Application context based on the locations"
  ([parent locations]
     (doto (new ClassPathXmlApplicationContext (into-array locations) parent)
       .refresh))
  ([locations]
     (new ClassPathXmlApplicationContext (into-array locations))))

(defn &init
  "Define spring funcs and return the Spring Application Context."
  [locs]
  (let [ctx (load-context locs)]
    (def ^:dynamic *spring-context* ctx)
    ctx))

(defn get-bean 
  [context name] (. context getBean name))

(defmacro typed-bean [ctx key]
  (let [rtnval (gensym "rtnval") cls (gensym "cls") ]
    `(fn []
       (let [bean# (get-bean ~ctx ~key)
         ~cls (.getType ~ctx ~key)]
     (let [~(with-meta rtnval {:tag cls}) bean#] ~rtnval)))))


(defn create-bean-map
  "Create a map of bean names (as keywords) to functions.  Calling the function
will return the bean with the given name.

ctx - The Spring Application Context"
   ([ctx]
     (let [names (seq (org.springframework.beans.factory.BeanFactoryUtils/beanNamesIncludingAncestors ctx))]
       (apply hash-map (mapcat (fn [f]
                    [(keyword f) (typed-bean ctx f)]) names)))))


(defn &beans [] (create-bean-map (&ctx)))

(defn &&  "Get a bean.  Accepts a string, symbol or keyword"
  ([name]
     (if-let [f (get (&beans) (keyword name))] (f))))

(defmacro with-spring
  [[& beans] & body]
    `(let [badones# (filter  (fn [b#] (not (&& b#))) ~(reduce conj [] (map keyword beans)))]
       (if (seq badones#) (throw (IllegalArgumentException. (str "Undefined beans:" (apply str badones#)))))
       (let ~(reduce conj []
             (mapcat
              (fn [b]
                (vector
                 b
                 (list (list (keyword b) '(&beans)))))
              beans))
         ~@body)))