嵌入Groovy脚本时添加一些默认import

本文介绍了一种在Java项目中使用Groovy脚本的方法,并通过自定义Groovy类加载器实现常用类的自动导入,以此减少重复代码并提高开发效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

刚才给在做的项目里加了些便捷功能,把做法记下来。
我们在Java应用里嵌入了Groovy脚本。为了方便,业务里经常用的一些类可以默认import进来,让大家少写点重复代码。幸好,这种功能用Groovy来做毫不费力。

import groovy.lang.GroovyClassLoader;

import java.security.CodeSource;

import org.codehaus.groovy.ast.ClassHelper;
import org.codehaus.groovy.ast.ModuleNode;
import org.codehaus.groovy.control.CompilationFailedException;
import org.codehaus.groovy.control.CompilationUnit;
import org.codehaus.groovy.control.CompilerConfiguration;
import org.codehaus.groovy.control.Phases;
import org.codehaus.groovy.control.SourceUnit;
import org.codehaus.groovy.control.CompilationUnit.SourceUnitOperation;

public class CustomGroovyClassLoader extends GroovyClassLoader {
private final String[] DEFAULT_IMPORT_CLASSES = {
"rednaxelafx.sample.Foo",
"rednaxelafx.sample.Bar"
};

/**
* Validate classes.
*
* Because the specified default import classes might not be present in
* the during runtime, they have to be validated first, otherwise Groovy
* won't compile the code.
*
* @param className the name of the class to validate
* @return true iff the class exists and is valid
*/
private boolean isClassValid(String className) {
try {
loadClass(className, false);
return true;
} catch (ClassNotFoundException e) {
return false;
}
}

private static String getClassSimpleName(final String className) {
return className.substring(className.lastIndexOf('.') + 1);
}

private static boolean alreadyImported(final String alias, final ModuleNode ast) {
return ast.getImport(alias) != null;
}

/**
* add default imports
*/
@Override
protected CompilationUnit createCompilationUnit(
CompilerConfiguration config, CodeSource source) {
CompilationUnit compUnit = super.createCompilationUnit(config, source);
compUnit.addPhaseOperation(new SourceUnitOperation() {
public void call(SourceUnit source) throws CompilationFailedException {
ModuleNode ast = source.getAST();
for (String className : DEFAULT_IMPORT_CLASSES) {
String simpleClassName = getClassSimpleName(className);
if (isClassValid(className) && !alreadyImported(simpleClassName, ast)) {
ast.addImport(simpleClassName, ClassHelper.make(className));
}
}
}
}, Phases.CONVERSION);
return compUnit;
}
}


直接用ast.addImport()的话,这些添加的“默认”import实际上是被append到原本的import列表的后面了。Groovy里后import的比先import的要更优先,所以这种默认import可能会带来干扰。要注意。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值