5

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

我正在寻找的是与此等效的 Clojure

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

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

有没有 Clojure 方法可以做到这一点?

4

2 回答 2

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

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

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

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

于 2013-06-05T02:23:43.960 回答
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)))
于 2013-06-05T16:35:08.360 回答