我现在已经看到几个项目以实际配置依赖于仅在运行时可用的内容结束的点结束.
配置Java程序的典型方法是根据某些特定于应用程序的规则读取一个或多个属性文件,然后根据其值采取操作.在某种程度上,这会破坏,您需要在配置中使用实际的程序逻辑,然后可以使用标志指示并向您的应用程序添加代码,然后处理该标志.
我想知道一个小的Lisp配置阅读器模块是否是一个更好的选择,其中要读取的文件不是属性文件,而是一个Lisp程序,然后通过eval来创建表示配置的最终数据结构.然后,运行时库中的一组最小函数将允许字符串操作,甚至可能调用JVM.试想一下"根据当前主机名构建一个URL".
我对一个带有铃声和口哨声的完整Lisp引擎不感兴趣,但只是一个用于此目的的小型库,它可以包含在甚至小程序中,而不需要包含Lisp引擎的大型jar.
这样的库存在吗?
建议?
编辑2012-01-20:我最初发现所有候选人都不受欢迎,但已经决定将其用作1998年jscheme 1.4版本的Maven练习.项目在https://github.com/ravn/jscheme-1998
编辑2012-12-11:事实证明,Scheme中解释的程序和宿主Java程序之间的集成层比我原先想的更重要,而且我需要在项目中能够提供带有JAX的类 - WS注释在运行时,我无法用JScheme做,但我可以用Groovy做.允许在库中使用代码片段的小型配置库的想法仍然有效,但我最终需要更多才能使它有用.
我知道你想要一个小尺寸和运行时.Scheme是易于嵌入的常用选择,也是我的首选.但是,我没有关于该领域的信息.我的第二个选择是Clojure:
使用Clojure的相应代码:
import clojure.lang.RT;
import clojure.lang.Var;
import clojure.lang.Compiler;
import java.io.FileReader;
import java.io.FileNotFoundException;
public class ClojTest {
public static void main(String[] args) throws Exception {
try {
Compiler.load(new FileReader("hello.clj"));
} catch(FileNotFoundException e) { return; }
System.out.println("Message: '"+ RT.var("user", "msg").get() +"'");
// Values
int answer = (Integer) RT.var("user", "answer").get();
// Function calls
System.out.println(RT.var("user", "countdown").invoke(42));
}
}
Run Code Online (Sandbox Code Playgroud)
与hello.clj:
(ns user)
(defn countdown [n]
(reduce + (range 1 (inc n))))
(def msg "Hello from Clojure!")
(def answer (countdown 42))
Run Code Online (Sandbox Code Playgroud)
运行time java ClojTest一段时间平均产生0.75秒.Clojure编译脚本有很大的代价!
优秀的小型解决方案是嵌入式Java方案.在许多实现中,我发现并测试了JScheme.(API看起来没问题:http://jscheme.sourceforge.net/jscheme/doc/api/index.html)
Java中一个简单的主程序:
import jscheme.JScheme;
import jscheme.SchemeException;
import java.io.*;
public class SchemeTest {
public static void main(String[] args) {
JScheme js = null;
try {
js = new JScheme();
js.load(new FileReader("config.scm"));
} catch (FileNotFoundException e) { return; }
System.out.println("Message: '" + js.eval("msg") + "'");
// Values
int answer = (Integer) js.eval("answer");
// Function calls
System.out.println(js.call("countdown", 42));
}
}
Run Code Online (Sandbox Code Playgroud)
一个例子config.scm:
(define (countdown x)
(define (loop x acc)
(if (= x 0)
acc
(loop (- x 1) (+ acc x))))
(loop x 0))
;;; config variables
(define msg "Hello from JScheme!")
;; tail calls are optimized as required
(define answer (countdown 42))
Run Code Online (Sandbox Code Playgroud)
该方案每次都在启动时进行解释,因此这是配置的不错选择.JScheme的优点包括:
基准更新:此代码在0.13秒内运行.与Clojure版本的时间相比,这非常快.