groovy 提供包含机制吗?

发布于 2024-08-02 10:22:43 字数 242 浏览 10 评论 0原文

我们正在为 Groovy 脚本寻找一种包含机制,以便为横切关注点留出空间。

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

但如果我们在每个 Web 服务端点中编码,这就是样板代码。

我们正在 php 中搜索类似 include() 的内容,其中包括其他 groovy 脚本,有什么想法可以做到这一点吗?

We are searching for an include mechanism for groovy scripts to have space for cross-cutting-concerns.

In my example we have, web service endpoints as groovy scripts and want to log to our web service protocol. for that we use our implicit object (getting from our framework) to create the logging statement.

But this is boilerplate code if we code this in every web service endpoint.

We are searching for something like include() in php, that includes other groovy scripts, are there any ideas how to do this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

待"谢繁草 2024-08-09 10:22:44

Groovy 将其文件视为对象(将其视为自动换行)。它使 java 类路径中的所有 .groovy 文件都可以作为类使用。因此,如果您有文件 util.groovy,其中包含类似以下内容:

def static AuxMethod() {
    return "Hello World"
}

要从另一个文件调用它,您只需编写:

println util.AuxMethod()

就是这样。再次强调,只需确保您的 util.groovy 文件位于类路径中即可。

Groovy treats its files as objects (think of it as of automatic wrapping). And it makes all .groovy files within the java classpath available as classes. So if you have the file util.groovy, that contains something like this inside:

def static AuxMethod() {
    return "Hello World"
}

To call it from another file you just write:

println util.AuxMethod()

That's it. Again, just make sure that your util.groovy file is in the classpath.

满栀 2024-08-09 10:22:44

要从当前脚本调用脚本 u.groovy,将原始参数传递给 u.groovy,运行

run(new File('u.groovy'), args)

显然,您还可以发送您想要的任何字符串参数:

run(new File('u.groovy'),
        ['one', new File('two.text').absolutePath] as String[])

To invoke script u.groovy from the current script, passing along the original arguments to the u.groovy, run

run(new File('u.groovy'), args)

Obviously, you could also send any String arguments that you want to:

run(new File('u.groovy'),
        ['one', new File('two.text').absolutePath] as String[])
〃温暖了心ぐ 2024-08-09 10:22:44

既然您已经提到了“横切关注点”,我想说您需要拦截您的 Web 服务调用 AOP 风格(不是包含机制)。

Grails 与 Spring 框架完全集成 ,因此这是利用 Spring AOP 功能的一个不错的选择。看一下grails官方指南的这一章:
http://grails.org/doc/latest/guide /14.%20Grails%20and%20Spring.html 并搜索单词 AOP。

也许有一种纯粹的常规方式来执行AOP,但我会去与圣杯和弹簧。

Since you already mentioned “cross-cutting-concerns” I’d say that you need to intercept your webservice calls AOP style (not an include mechanism).

Grails is completely integrated with Spring framework, so this makes for a good option for exploiting Spring AOP features. Take a look at this chapter from grails official guide:
http://grails.org/doc/latest/guide/14.%20Grails%20and%20Spring.html and search for word AOP.

Maybe there is a purely groovy way of doing AOP, but I'd go with grails and spring.

空城旧梦 2024-08-09 10:22:44

查看评估(文件)函数:

 Object evaluate(File file) 

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

Look at the evaluate(File) function:

 Object evaluate(File file) 

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

浅笑轻吟梦一曲 2024-08-09 10:22:44

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

  1. 创建继承父 Groovy 类的类。将您的共享代码放入基类中。

  2. 使用 ScriptBaseClass 请参阅 http://groovy.codehaus.org/Embedding+Groovy 。您的所有脚本都将在该类上创建。

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

所有这些都很好用。我的偏好是 ScriptBaseClass。如果通用代码是 Groovy(ScriptBaseClass必须是 groovy 类。它不能是 java 类。),这效果最好。

当然,对于所有这些项目,您仍然需要实际调用Groovy 代码中的常用方法。例如:

doCommonStuff();
.
. do the rest of it here
.

我认为这还不算太糟糕。当然,与添加某种 #include 预处理器语句大致相同。

最后,所有这些都假设您可以访问调用 Groovy 代码的 java 程序。如果不是这种情况,您仍然可以使用静态导入。这只是多一行代码。

import static com.mycompany.mycode.doCommonStuff
doCommonStuf()
.
. do the rest of it here
.

I did some research on this for a Domain Specific Language I was creating. There are three possibilities:

  1. Create your classes as inheriting a parent groovy class. Put your shared code in the base class.

  2. Use the ScriptBaseClass see http://groovy.codehaus.org/Embedding+Groovy . This is a class upon which all of your scripts will be created.

  3. Use the import static methods capability. Note that you can do this inside the java container (see http://mrhaki.blogspot.com/2011/06/groovy-goodness-add-imports.html ).

All of these work great. My preference is the ScriptBaseClass. This works best if the common code is Groovy (the ScriptBaseClass must be a groovy class. It can not be a java class.)

Of course, with all of these items, you will still need to actually call the common method in your groovy code. For example:

doCommonStuff();
.
. do the rest of it here
.

That's not too awful, I don't think. Certainly about the same as adding some sort of #include pre-processor statement.

And finally, all of this assumes that you have access to the java program which is calling your Groovy code. If that's not the case, you can still use the static imports. It's just one extra line of code.

import static com.mycompany.mycode.doCommonStuff
doCommonStuf()
.
. do the rest of it here
.
埖埖迣鎅 2024-08-09 10:22:44

我为我的脚本创建了一个预处理器。它搜索特定的 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());
    }
}

I created a preprocessor for my scripts. It searchs for a specific include pattern, here is a example:

public final class IncludePreprocessor {

    @FunctionalInterface
    public interface IncludeLoader {

        InputStream load(String include) throws IOException;

    }

    private static final Pattern INCLUDE_PATTERN = Pattern.compile("include\\s+(.+)
quot;);

    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;
    }
}

And how to use it:

//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());
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文