核心技术(卷二)06、第10章-脚本、编译和注解处理

脚本、编译和注解处理

Java平台的脚本

添加脚本引擎

Java SE默认支持对JavaScript的解释。

ScriptEngineManager manager = new ScriptEngineManager();
//获取所有发现的引擎工长列表
List<ScriptEngineFactory> factoryList = manager.getEngineFactories();
for(ScriptEngineFactory factory : factoryList){
	//获取引擎工厂名称
    logger.info("engine name: "+factory.getEngineName());
	//该引擎工厂所了解的名字
    logger.info("getNames: " + factory.getNames());
	//该引擎工厂所了解的文件扩展名
    logger.info("getExtensions: " + factory.getExtensions());
	//该引擎工厂所了解的MIME类型
    logger.info("getMimeTypes: " + factory.getMimeTypes());
}

默认情况下,输出结果如下:

Java SE 8之前默认使用的是Rnino js脚本引擎,从Java SE 8 开始,默认使用Nashorn作为js脚本引擎。

如果需要对其它脚本进行支持,需要添加相应的JAR包。如增加对Groovy脚本的支持:

<dependency>
    <groupId>org.codehaus.groovy</groupId>
    <artifactId>groovy-all</artifactId>
    <version>3.0.3</version>
    <type>pom</type>
</dependency>

只需要加入Groovy的jar包,项目就可以支持Groovy了。

获取脚本引擎对象

通过上面对引擎的探测,我们知道了当前应用支持的脚本。我们就可以根据使用ScriptEngineMaanager来获得引擎对象:

//指定名称获取
ScriptEngine jsEngine = manager.getEngineByName("JavaScript");
//指定扩展名获取
ScriptEngine jsEngine = manager.getEngineByExtension("js");
//指定MIME类型获取
ScriptEngine jsEngine = manager.getEngineByMimeType("application/javascript");

脚本赋值与绑定

一旦获得了引擎,我们就可以调用脚本了。

//直接执行脚本字符串
Object result = jsEngine.eval(jsString);
//若脚本在一个文件中,需要先打开一个Reader,然后再调用
Object result = jsEngine.eval(reader);
变量绑定
//引擎作用域
jsEngine.put(k,value);//为脚本中的某个变量赋值

jsEngine.get(k);//获取脚本中某个变量的值

// 全局作用域
manager.put(k,value);

除了想引擎或全局作用域绑定变量到外,还可以将所有变量绑定集中在类型为Bindings的对象中,然后将其传递给eval方法:

Bindings scops = engine.createBindings();
scops.put(k,value);
engine.eval(scripteString,scops);
重定向输入和输出
StringWriter writer = new StringWriter()
engine.getContext().setWriter(new PrintWriter(writer));

通过上面的设置,脚本的pringtprintln函数产生的输出都将输出到writer。

调用脚本的函数和方法

如果脚本引擎实现了Involcable接口,那么我们可以这样来调用脚本函数:

if (enging instanceof Invocable){
	enging.eval(reader);
	Invocable invocable = (Invocable)engine;
    Object result = (String)invocable.invokeFunction(methodName, param1,param2);
}

如果脚本语言是面向对象的,那么我们可以这样来调用:

var Tools = {
    createNew: function () {
        var tools = {};
        tools.plus = function (a, b) {
            return a + b;
        }
        return tools;
    }
};

Tools.createNew();
Reader reader = new FileReader("script.js");
ScriptEngine jsEngien = Chapter2_10.getEngine("js");
if (jsEngien instanceof Invocable){
	Object tool = jsEngien.eval(reader);//获取脚本对象的代理
    Util.info(((Invocable)jsEngien).invokeMethod(tool,"plus",1,2));
}     

invokeMethod方法的第一个入参是脚本语言编写的对象的一个代理,它必须是前一个对脚本引擎调用的结果。

我们还可以通过Java接口来调用脚本函数:

我们先定义接口:

public interface Tools{
	int plus(int a, int b);
}

然后我们在脚本中实现对应的方法:

function plus(a,b){
	return a+b;
}
jsEngien.eval(reader);
Tools tools = ((Invocable)jsEngien).getInterface(Tools.class);
int result = tools.plus(1,2);
编译脚本

如果一个脚本需要被重复的执行,那么我们可以将脚本代码编译为某种中间格式,以提高程序的执行效率。

CompiledScript script = null;
if (engine instanceof Compilable){
	script = ((Compilaable)engine).compile(reader);
}
if(script != null){
	script.eval();
	...
}else{
	engine.eval();
	...
}

注解

在Java中,注解被当做 修饰符 来使用的,它被置于被注解项之前,中间没有分号。注解项可以是类、方法、域或者局部变量,这些注解可以被放置在任何一个可以放置想public或者static这样的修饰符的地方。

每个注解都必须通过一个 注解接口 进行定义。这些接口中的方法与注解中的元素相对应。如:

@Target(ElementType.METHOD)
@Retention(RetentionPlicy.RUNTIME)
public @interface Test{
	...
	long timeout() default 0L;
}
  1. @interface:声明创建了一个真正的Java接口。处理注解的工具将接收那些实现了该注解接口的对象。

  2. timeout() :处理接口的工具可以调用该方法来检索某个特定Test注解的timeout元素。

  3. Target(ElementType.METHOD):定义该注解只能用于注解方法

  4. Retention(RetentionPlicy.RUNTIME):当类文件加载到虚拟机时,被注解的方法任被保留。

注解语法

注解是由 注解接口(@interface 定义的,每个元素声明都具有下面这种格式:

type elementName();

或者:

type elementName() default value();

(未完待续。。。)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值