Что на самом деле означает, что конфигурация API представляет зависимости, а реализация - нет, в Gradle? - PullRequest
1 голос
/ 14 февраля 2020

Я прошел Официальное занятие c и множество вопросов StackOverflow о разнице между api и implementation конфигурациями. Я думаю, что понимаю основы c, но я действительно хочу понять, что это означает под зависимостями, выставлены или не выставлены.

Это то, что я получил до сих пор. Когда я публикую sh мою библиотеку Java (записанную в Kotlin, но не релевантную), область зависимостей в опубликованном файле pom равна либо complie, когда используется api, либо runtime, когда * Используется 1011 *, то есть

dependencies {
    api "..."
}
<dependency>
      <groupId>...</groupId>
      <artifactId>...</artifactId>
      <version>...</version>
      <scope>compile</scope> 
</dependency>
dependencies {
    implementation "..."
}
<dependency>
      <groupId>...</groupId>
      <artifactId>...</artifactId>
      <version>...</version>
      <scope>runtime</scope> 
</dependency>

Так означает ли в этом случае предоставление зависимостей в действительности просто добавление их в classpath (область компиляции)?

Один из многих в ответах api против implementation говорится, что речь идет просто об оптимизации сборки, имеет смысл, что время сборки будет сокращено, если мы не добавим все в classpath, может быть?

И дополнительный вопрос , Gradle do c говорит, что api конфигурация поставляется с плагином java-library, но, очевидно, я могу использовать его без применения плагина, как это возможно?

// Gradle 6.1.1
plugins {
    id 'org.jetbrains.kotlin.jvm' version 'XXX'
}
dependencies {
    api "myLibrary"
}

1 Ответ

1 голос
/ 14 февраля 2020

Так значит ли, что раскрытие зависимостей в этом случае означает просто добавление их в classpath (область компиляции)?

Да, это просто вопрос наличия их на пути к классам компиляции потребителя. или нет.

Один из многих ответов о реализации API говорит, что речь идет просто об оптимизации сборки, имеет смысл, что время сборки будет сокращено, если мы не добавим все в classpath, может быть?

Хорошо, хороший дизайн программного обеспечения не раскрывает внутренние детали реализации. Вот почему в коде есть publi c и закрытые члены класса. Вы можете утверждать, что этот принцип равен solid, когда речь идет и о зависимостях. Я вижу следующие преимущества:

  • Потребитель неявно начинает полагаться на «внутренние» транзитивные зависимости. Если бы они это сделали, это означало бы, что вы не можете удалить их из библиотеки, не нарушив потребителей.
  • Сокращенный путь к классу может сделать компиляцию немного быстрее. Я не думаю, что это имеет большое значение для обычных проектов. Может быть, это более эффективно, если вы полагаетесь на Java или Kotlin процессоры аннотаций или Groovy AST-преобразования, которые ощущаются как сканирование всего пути к классам через каждый раз.
  • Отсутствие ненужных модулей на пути к классам компиляции означает библиотека не должна будет перекомпилироваться, если эти модули изменятся.

Последний вариант - самое большое преимущество в моем мнении. Допустим, у вас есть большой мультипроект, в котором совместно используемый подпроект внутренне зависит от Apache Commons Lang. Если вы объявили Lang зависимостью API и обновили ее, то все остальные проекты, использующие этот общий проект, необходимо перекомпилировать. Если вы объявите его как зависимость реализации, этого не произойдет. Все эти проекты все равно необходимо будет повторно протестировать по причине, поскольку поведение среды выполнения могло измениться (это правильно обрабатывается в Gradle).

И дополнительный вопрос, Gradle do c говорит, что конфигурация api поставляется с java -библиотечным плагином, но, очевидно, я могу использовать его без применения плагина, как это возможно?

Это потому, что плагин Kotlin также объявляет Конфигурация API. Он имеет ту же семантику, что и настроенный плагином java -library.

Если ваш проект является многопроектным, вы все равно можете добавить плагин java -library, даже если он использует Kotlin плагин. Дополнительное изменение, которое это вызовет, состоит в том, что потребители увидят выходной каталог для скомпилированных классов вместо окончательного файла JAR. Это избавляет от необходимости создавать банку во время обычной разработки, что должно сократить время сборки. С другой стороны, по-видимому, существует потенциальная проблема производительности на Windows, если у вас много классов в одном проекте, поэтому обычный ваш пробег может варьироваться Отказ от ответственности также применим и здесь (я не хотя я не знаю, сколько «много»).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...