[英]How Gradle Plugin add method to a specific block?
我想知道 Gradle 如何實現這種機制:將特定方法添加到僅在該塊中工作的腳本塊。
例如,如果我想使用implementation
方法,我必須apply plugin: 'java'
,但我只能在依賴項中使用implementation
dependencies{}
dependencies
塊只是一個DependencyHandler
。 默認實現是DefaultDependencyHandler
。 請注意,它實現MethodMixIn
:
裝飾域 object 類型可以選擇實現此接口以動態公開方法,除了在類型上靜態聲明的方法。 注意,當一個類型實現這個接口時,動態 Groovy 調度將不會用於發現不透明的方法。 也就是說,
methodMissing()
等方法將被忽略。
所以,這個mixin有點像methodMissing
中的methodMissing。 每當在 Groovy object 上調用未知方法時,如果它有methodMissing
方法,則調用它。 MethodMixIn
似乎工作類似。 它定義了一個方法:
MethodAccess getAdditionalMethods();
讓我們看看它是如何在DefaultDependencyHandler
中實現的?
public MethodAccess getAdditionalMethods() {
return dynamicMethods;
}
其中dynamicMethods
被初始化為:
dynamicMethods = new DynamicAddDependencyMethods(configurationContainer, new DirectDependencyAdder());
讓我們檢查一下DynamicAddDependencyMethods
。 首先,它定義了一個hasMethod
,當存在具有給定名稱的配置時返回true
:
public boolean hasMethod(String name, Object... arguments) {
return arguments.length != 0 && configurationContainer.findByName(name) != null;
}
應用 Java 插件后,您的configurations
將具有api
、 implementation
等對象。 因此, hasMethod("api")
將返回true
,而hasMethod("API")
– false
,除非您有另一個插件提供具有該名稱的配置。
最后,每當使用配置名稱時都會調用tryInvokeMethod
,例如dependencies
塊中的 function:
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();
}
}
如您所見,它只是查找命名配置並將依賴項添加到它。
它就是這樣制作的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.