簡體   English   中英

Gradle 插件如何將方法添加到特定塊?

[英]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將具有apiimplementation 對象。 因此, 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM