Обширная цитата из Документации Maven описывает это довольно четко:
Дополнительные зависимости используются, когда невозможно (по какой-либо причине) разделить проект на подмодули. , Идея заключается в том, что некоторые зависимости используются только для определенных функций проекта и не понадобятся, если эта функция не используется. В идеале такая функция должна быть разбита на подмодуль, который зависит от проекта основной функциональности. Этот новый подпроект будет иметь только необязательные зависимости, так как они вам понадобятся, если вы решите использовать функциональность подпроекта.
Однако, поскольку проект не может быть разделен (опять же, по какой-либо причине), эти зависимости объявлены необязательными. Если пользователь хочет использовать функциональность, связанную с необязательной зависимостью, он должен повторно объявить эту необязательную зависимость в своем собственном проекте. Это не самый ясный способ справиться с этой ситуацией, но и необязательные зависимости, и исключения из зависимостей являются решениями с ограничением.
Зачем использовать необязательные зависимости?
Необязательные зависимости экономят место и память. Они предотвращают создание проблемных c файлов jar, которые нарушают лицензионное соглашение или приводят к тому, что проблемы с classpath объединяются в WAR, EAR, fat jar и т. П.
Как работают необязательные зависимости?
Project-A -> Project-B
Диаграмма выше говорит о том, что Project-A зависит от Project-B. Когда A объявляет B как необязательную зависимость в своем POM, это отношение остается неизменным. Это похоже на нормальную сборку, в которой Project-B будет добавлен в путь к классам Project-A.
Project-X -> Project-A
Когда другой проект (Project-X) объявляет Project-A как зависимость в своем POM, необязательный характер зависимости вступает в силу. Project-B не включен в путь к классу Project-X. Вам нужно объявить это непосредственно в POM Project X для B, чтобы включить его в classpath X.
Практический пример: представьте, что вы разработчик библиотеки / фреймворка SuperLib
, который построен как один superlib.jar
. Ваша библиотека предоставляет несколько функций. Его основная функция (которую использует большинство пользователей) - внедрение зависимостей на основе сторонней библиотеки di
. Тем не менее, один из ваших классов - EmailApi
- предлагает функции для отправки электронной почты, используя стороннюю библиотеку email
. Поскольку superlib
является одним артефактом, для компиляции требуется di
и email
.
Теперь поставьте себя на место пользователя, который использует superlib
. Их интересуют особенности внедрения зависимостей. Это основная роль вашей библиотеки, поэтому зависимость между superlib
и di
будет , а не необязательной.
Однако большинство пользователей не заинтересованы в отправке электронных писем и могут беспокоит наличие бесполезной библиотеки email
и ее зависимостей, добавленных в их приложение (что приведет к увеличению размера их приложения и может вызвать версию зависимости cla sh между зависимостями email
и зависимостями приложения пользователя). Следовательно, вы должны пометить зависимость от email
как optional
. Пока пользователь не использует ваш класс EmailApi
, все будет работать нормально. Однако, если они используют EmailApi
, им потребуется зависимость email
, в противном случае приложение завершится с ошибкой во время выполнения с ClassNotFoundException для любого класса из email
, на который будет ссылаться в EmailApi
. Пользователю вашей библиотеки необходимо явно добавить зависимость email
в свой POM.
См. Также Когда использовать <optional>true</optional>
и когда использовать <scope>provided</scope>
.