groovy是否提供包含机制?

时间:2009-08-12 07:24:05

标签: web-services groovy include endpoint cross-cutting-concerns

我们正在寻找一种用于groovy脚本的包含机制,以便为横切关注提供空间。

在我的示例中,我们将Web服务端点作为常规脚本,并希望登录到我们的Web服务协议。为此,我们使用隐式对象(从我们的框架中获取)来创建日志语句。

但如果我们在每个Web服务端点中对此进行编码,那么这是样板代码。

我们正在搜索php中的include(),包括其他groovy脚本,有什么想法如何做到这一点?

7 个答案:

答案 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)

查看评估(文件)功能:

 Object evaluate(File file) 

http://groovy.codehaus.org/api/groovy/lang/Script.html

答案 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)

我为我正在创建的领域特定语言做了一些研究。有三种可能性:

  1. 创建类作为继承父groovy类。将您的共享代码放在基类中。

  2. 使用ScriptBaseClass,请参阅http://groovy.codehaus.org/Embedding+Groovy。这是一个将在其上创建所有脚本的类。

  3. 使用导入静态方法功能。请注意,您可以在java容器中执行此操作(请参阅http://mrhaki.blogspot.com/2011/06/groovy-goodness-add-imports.html)。

  4. 所有这些都很棒。我的偏好是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)

答案 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());
    }
}