我有很多spring bean可以封装现有的业务逻辑。现在我希望在我的新Clojure Compojure应用程序中重用那些Spring Beans。我该怎么做?
我正在寻找的是Clojure相当于此
Context context = new ClassPathXmlApplicationContext(....);
MyBean mybean = context.get("mybean", MyBean.class)
有没有Clojure这样做的方式?
答案 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)))