我们正在寻找一种用于groovy脚本的包含机制,以便为横切关注提供空间。
在我的示例中,我们将Web服务端点作为常规脚本,并希望登录到我们的Web服务协议。为此,我们使用隐式对象(从我们的框架中获取)来创建日志语句。
但如果我们在每个Web服务端点中对此进行编码,那么这是样板代码。
我们正在搜索php中的include(),包括其他groovy脚本,有什么想法如何做到这一点?
答案 0 :(得分:10)
Groovy将其文件视为对象(将其视为自动换行)。它使java类路径中的所有.groovy文件都可用作类。因此,如果您有文件util.groovy,其中包含类似的内容:
def static AuxMethod() {
return "Hello World"
}
要从另一个文件中调用它,您只需编写:
println util.AuxMethod()
就是这样。再次,只需确保您的util.groovy文件位于类路径中。
答案 1 :(得分:2)
要从当前脚本调用脚本u.groovy
,将原始参数传递给u.groovy,运行
run(new File('u.groovy'), args)
显然,你也可以发送你想要的任何String参数:
run(new File('u.groovy'),
['one', new File('two.text').absolutePath] as String[])
答案 2 :(得分:1)
答案 3 :(得分:1)
由于您已经提到过“跨领域问题”,我会说您需要拦截您的Web服务调用AOP样式(不是包含机制)。
Grails与Spring framework完全集成,因此这为利用Spring AOP功能提供了一个很好的选择。从grails官方指南看一下这一章: http://grails.org/doc/latest/guide/14.%20Grails%20and%20Spring.html并搜索单词AOP。
也许有purely groovy way做AOP,但我会用grails和spring。
答案 4 :(得分:1)
我为我正在创建的领域特定语言做了一些研究。有三种可能性:
创建类作为继承父groovy类。将您的共享代码放在基类中。
使用ScriptBaseClass,请参阅http://groovy.codehaus.org/Embedding+Groovy。这是一个将在其上创建所有脚本的类。
使用导入静态方法功能。请注意,您可以在java容器中执行此操作(请参阅http://mrhaki.blogspot.com/2011/06/groovy-goodness-add-imports.html)。
所有这些都很棒。我的偏好是ScriptBaseClass。如果公共代码是Groovy(ScriptBaseClass 必须是一个groovy类。它不能是一个java类。)
当然,对于所有这些项目,您仍然需要在groovy代码中实际调用common方法。例如:
doCommonStuff();
.
. do the rest of it here
.
这不太可怕,我不这么认为。当然与添加某种#include预处理器语句大致相同。
最后,所有这些假设您可以访问调用Groovy代码的java程序。如果不是这种情况,您仍然可以使用静态导入。这只是一行额外的代码。
import static com.mycompany.mycode.doCommonStuff
doCommonStuf()
.
. do the rest of it here
.
答案 5 :(得分:0)
我发现这个邮件列表很有帮助。 http://groovy.329449.n5.nabble.com/Groovy-scripts-Reusing-declared-methods-in-other-scripts-How-Include-td5703723.html
答案 6 :(得分:0)
我为脚本创建了预处理器。它搜索特定的include
模式,这是一个示例:
public final class IncludePreprocessor {
@FunctionalInterface
public interface IncludeLoader {
InputStream load(String include) throws IOException;
}
private static final Pattern INCLUDE_PATTERN = Pattern.compile("include\\s+(.+)$");
private final IncludeLoader includeLoader;
public IncludePreprocessor(IncludeLoader includeLoader) {
this.includeLoader = includeLoader;
}
public boolean preprocess(InputStream mainScript, Writer outputScript) throws IOException {
boolean preprocessed = false;
try (Scanner sc = new Scanner(mainScript)) {
while (sc.hasNextLine()) {
String line = sc.nextLine();
Matcher m = INCLUDE_PATTERN.matcher(line);
if (m.matches()) {
outputScript.append("//").append(line).append(System.lineSeparator());
String include = m.group(1);
try (InputStream in = includeLoader.load(include)) {
StringWriter sw = new StringWriter();
preprocess(in, sw);
outputScript.append(sw.toString()).append(System.lineSeparator());
preprocessed = true;
}
outputScript.append("//").append(line).append(" [EOF]").append(System.lineSeparator());
} else {
outputScript.append(line).append(System.lineSeparator());
}
}
}
return preprocessed;
}
}
以及如何使用它:
//common.groovy
def sum(a,b) {
a + b
}
// main.groovy
include common.groovy
sum(1,2)
// Demo.java
public class Demo {
public static void main(String[] args) {
IncludePreprocessor ip = new IncludePreprocessor(include -> new FileInputStream("./" + include));
StringWriter sw = new StringWriter();
ip.preprocess(new FileInputStream("./main.groovy", sw));
System.out.println(sw.toString());
}
}