Java Gradle插件如何将方法添加到特定块?

Java Gradle插件如何将方法添加到特定块?,java,gradle,groovy,Java,Gradle,Groovy,我想知道Gradle是如何实现这种机制的:向脚本块添加一个只在该块中工作的特定方法 例如,如果我想使用实现方法,我必须应用plugin:'java',但我只能在依赖项{}依赖项块中使用实现。 默认实现是。 请注意,它实现了: 修饰的域对象类型可以选择性地实现此接口,以动态公开在该类型上静态声明的方法之外的方法。 请注意,当类型实现此接口时,动态Groovy分派将不会用于发现不透明方法。 也就是说,诸如methodMissing()之类的方法将被忽略 所以,这个mixin有点像Groovy中的。

我想知道Gradle是如何实现这种机制的:向脚本块添加一个只在该块中工作的特定方法


例如,如果我想使用
实现
方法,我必须
应用plugin:'java'
,但我只能在
依赖项{}
依赖项
块中使用
实现
。 默认实现是。 请注意,它实现了:

修饰的域对象类型可以选择性地实现此接口,以动态公开在该类型上静态声明的方法之外的方法。 请注意,当类型实现此接口时,动态Groovy分派将不会用于发现不透明方法。 也就是说,诸如
methodMissing()
之类的方法将被忽略

所以,这个mixin有点像Groovy中的。 每当对Groovy对象调用未知方法时,如果它有
methodMissing
method,就会调用它。
MethodMixIn
的工作原理似乎类似。 它定义了一种方法:

MethodAccess getAdditionalMethods();
让我们看看它是如何在
DefaultDependencyHandler
中实现的

public MethodAccess getAdditionalMethods() {
    return dynamicMethods;
}
其中,
dynamicMethods
初始化为:

dynamicMethods = new DynamicAddDependencyMethods(configurationContainer, new DirectDependencyAdder());
让我们检查一下。 首先,它定义了一个
hasMethod
,当存在具有给定名称的配置时,该方法返回
true

public boolean hasMethod(String name, Object... arguments) {
    return arguments.length != 0 && configurationContainer.findByName(name) != null;
}
应用Java插件后,您的
配置
将有
api
实现
和。 因此,
hasMethod(“api”)
将返回
true
,而
hasMethod(“api”)
false
,除非您有另一个插件以该名称提供配置

最后,只要将配置名称用作
dependencies
块中的函数,就会调用中的
tryInvokeMethod
in:

public DynamicInvokeResult tryInvokeMethod(String name, Object... arguments) {
    if (arguments.length == 0) {
        return DynamicInvokeResult.notFound();
    }
    Configuration configuration = configurationContainer.findByName(name);
    if (configuration == null) {
        return DynamicInvokeResult.notFound();
    }

    List<?> normalizedArgs = CollectionUtils.flattenCollections(arguments);
    if (normalizedArgs.size() == 2 && normalizedArgs.get(1) instanceof Closure) {
        return DynamicInvokeResult.found(dependencyAdder.add(configuration, normalizedArgs.get(0), (Closure) normalizedArgs.get(1)));
    } else if (normalizedArgs.size() == 1) {
        return DynamicInvokeResult.found(dependencyAdder.add(configuration, normalizedArgs.get(0), null));
    } else {
        for (Object arg : normalizedArgs) {
            dependencyAdder.add(configuration, arg, null);
        }
        return DynamicInvokeResult.found();
    }
}
publicdynamicinvokeresult tryInvokeMethod(字符串名称、对象…参数){
if(arguments.length==0){
返回DynamicInvokeResult.notFound();
}
Configuration=configurationContainer.findByName(名称);
if(配置==null){
返回DynamicInvokeResult.notFound();
}
List normalizedArgs=CollectionUtils.flatteCollections(参数);
if(normalizedArgs.size()==2&&normalizedArgs.get(1)闭包实例){
返回DynamicInvokeResult.found(dependencyAdder.add(配置,normalizedArgs.get(0),(闭包)normalizedArgs.get(1));
}else if(normalizedArgs.size()==1){
返回DynamicInvokeResult.found(dependencyAdder.add(配置,normalizedArgs.get(0),null));
}否则{
用于(对象参数:normalizedArgs){
add(配置,arg,null);
}
返回dynamicInvokerResult.found();
}
}
如您所见,它只是查找一个命名的配置并向其中添加依赖项


这就是它的制作方法。

这个问题困扰了我好几个月,非常感谢你的回答@ratsafalig-只是一个建议:如果答案有帮助,你可以投赞成票。但是,如果你是问这个问题的人,你也应该考虑一下,点击复选标记。这一步是完全可选的,但是。