抠腚爱揉曼 Coding Iron Man

16Jul/105

用Groovy给系统开个万能console

系统上线了,有BUG,数据错了,用户抱怨了,然后线上DB权限又不开放给开发,走流程各种纠结(还扣分……靠),这时候应该怎么办呢?

一般来说我们会做个console,把可能需要的功能都做上去,但往往不可能全都考虑周全,所以如果我的console可以动态的执行各种有的没得功能该多好。

嗯……所以我们可以想办法让系统跑一段我们自定义的代码,这时候Groovy显然是个很好的选择(对于Java应用来说)。它将会和你的应用跑在同一个容器中,可以获取应用的classLoader,也就是说它可以控制应用的每一个部分。

好,然后你需要做的就是:

1.把groovy-all.jar依赖进来
2.开放一个接口给console,入参就是groovy脚本字串
3.编译groovy为Script class,run it

这时候基本上已经完事了,但为了方便我们写groovy,我们还可以利用Groovy的Closure给脚本加入一些内建方法。

Map map = new HashMap();
map.put("newInstance", new Closure(null) {
	public Object doCall(String className) throws Exception {
		ClassLoader loader = Thread.currentThread().getContextClassLoader();
		Class clazz = Class.forName(className, false, loader);
		return clazz.newInstance();
	}
});

构建类似这样的map,binding给script,就可以在script中使用newInstance()来获取一个类实例。

然后如果系统使用了spring(一般都会啦),使用spring的ApplicationContextAware接口注入一个applicationContext,然后给groovy脚本binding这样的东西~

Map<String, Object> map = new HashMap<String, Object>();
map.put("getSpringBean", new Closure(null) {
	public Object doCall(String beanName) {
		// 简单的获取了下applicationContext,假设它被注入在SpringApplicationContext的static字段中
		return SpringApplicationContext.applicationContext.getBean(beanName);
	}
});

就可以使用getSpringBean()来获取spring管理的bean了,这下依赖关系也不用关心了。

下面是一个简单的例子

public static void main(String[] args) {
	String groovyScript = "newInstance(\"us.vifix.a.TouTouMoMoGroovy\")";
	GroovyShell shell = new GroovyShell();
	Script script = shell.parse(groovyScript);
	Map<String, Object> map = new HashMap<String, Object>();
	map.put("newInstance", new Closure(null) {
		public Object doCall(String className) throws Exception {
			ClassLoader loader = Thread.currentThread().getContextClassLoader();
			Class<?> clazz = Class.forName(className, false, loader);
			return clazz.newInstance();
		}
	});
	script.setBinding(new Binding(map));
	System.out.println(script.run());
}

Posted by Anson

Comments (5) Trackbacks (0)
  1. 同学你把“高原”上的“空格”放进去了……

  2. “同学”这个万能的称呼。

  3. 注意加个链接。http://sun-otaku.appspot.com


Leave a comment

(required)

No trackbacks yet.