#java #spring #maven #maven-3
#java #spring #maven #maven-3
Вопрос:
Я разрабатываю модульное веб-приложение, в котором я использую maven. Скелет моего приложения следующий:
Скелет моего приложения с модулем share-services
Теперь я хочу импортировать некоторые классы Service-App1 в Service-App2, но без зависимостей Service-App1 (например, Module-App1, Util-App1 и внешних зависимостей).
Подводя итог, поскольку в App2 у меня есть составная единица сохранения Composite Persistence Unit, и я хочу поделиться некоторой бизнес-логикой между приложениями. Например, если в App1 у меня есть служба Spring, подобная этой:
public interface ContractService {
void processSomethings();
}
@Service
public class ContractServiceImpl implements ContractService {
public void processSomethings(){
//Manage some share entities
}
}
Я бы хотел использовать метод
processSomethings()
также в App1, как я могу это реализовать?
Комментарии:
1. Если вам это нужно отдельно, вам нужно создать отдельный модуль (maven module) и использовать это.
2. @khmarbaise Также я думал создать отдельный модуль (общий сервис), но вы можете предложить, как поместить его в мой скелет (от кого зависит, наследуется и какой проект является подмодулем)
Ответ №1:
Вам нужно создать проект (вывод jar), который содержит только те классы, которые являются общими для двух потребителей. Это может показаться накладными расходами, но это приводит к чистому, хорошо организованному коду. Если вы не можете этого сделать, это указывает на то, что у вас запутанная иерархия зависимостей. Я делаю это регулярно для реализации клиентов и служб веб-службы с общим jar, который содержит общие классы (т. Е. Клиент не должен ничего знать о классах DAO, но должен знать подпись операций веб-службы. Он также должен иметь доступ к классам POJO, которые определяют структуру данных и сообщений).
Кроме того, нужна ли вам зависимость hamcrest во время выполнения? Мой опыт показывает, что обычно для его области видимости может быть установлено значение test, поэтому он никогда не появляется в ваших скомпилированных артефактах.
Я не конвертирую родительские pom и, конечно же, не рассматривал бы двухуровневую структуру родительского pom, которую вы показываете. Мои возражения:
- Если вы обновляете родительский pom, вам затем необходимо обновить все дочерние pom, которые его используют, сводя на нет преимущество централизации вашей информации о зависимостях.
- Помещение объявлений модуля в родительский pom, похоже, приводит к циклической ссылке. Если вы измените родительский pom, он попытается скомпилировать модули, которые немедленно обратятся к родительскому, который еще недоступен в репозитории, поскольку его сборка не завершена. Я видел системы, в которых есть «родительская зависимость» и «родительская компиляция всех модулей», чтобы обойти это. Я использую родительские poms экономно, но только для установки версии компилятора и определения версий внешних зависимостей, таких как Spring и Apache commons jars.
Я хотел бы услышать аргументированный аргумент по этой теме.
Комментарии:
1. @kiviron Я использовал двухуровневый родительский pom, почему App1-Parent содержит разные внешние зависимости от App2-Parent (например, другую версию spring и внешнюю зависимость). Вместо моей основной проблемы я обновил свой вопрос своей новой структурой. Но теперь вот как импортировать этот новый модуль в мой проект (внешний зависимый или подмодуль). Можете ли вы помочь мне, поместив скелет вашего приложения?
Ответ №2:
Вам нужно добавить <exclusions>
раздел к вашей зависимости maven и перечислить переходные зависимости, которые вы не хотите наследовать.
Например, если мой pom.xml имеет <dependencies>
раздел, который выглядит следующим образом:
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
</dependencies>
…затем, когда я делаю mvn dependency:tree
, я получаю следующий вывод:
[INFO] ------------------------------------------------------------------------
[INFO] Building scratch 0.0.1-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-dependency-plugin:2.8:tree (default-cli) @ scratch ---
[INFO] com.nppc.mes:scratch:jar:0.0.1-SNAPSHOT
[INFO] - junit:junit:jar:4.11:test
[INFO] - org.hamcrest:hamcrest-core:jar:1.3:test
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
Если я решу, что мне действительно не нужна hamcrest-core
зависимость в моем проекте, я могу изменить свой pom.xml чтобы исключить это вот так:
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-core</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
…что дает мне mvn dependency:tree
вывод:
[INFO] ------------------------------------------------------------------------
[INFO] Building scratch 0.0.1-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-dependency-plugin:2.8:tree (default-cli) @ scratch ---
[INFO] com.nppc.mes:scratch:jar:0.0.1-SNAPSHOT
[INFO] - junit:junit:jar:4.11:test
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
Комментарии:
1. Исключения работают только с артефактами или, другими словами, с файлами jar, но не на уровне класса.
2. @khmarbaise В OP специально упомянуто, что он хочет исключить Module-App1 и Util-App1, которые являются файлами .jar в соответствии с его схемой.
Ответ №3:
Я не думаю, что вы можете, и я, конечно, надеюсь, что нет.
Одной из идей ОО-программирования была инкапсуляция, которая включает в себя идею сокрытия деталей реализации используемого вами класса. Предполагается, что вы не должны знать, от каких классов это зависит, хотя предполагается, что вы сможете обнаружить, какие библиотеки он использует. Но для целей использования класса в библиотеке вы не должны иметь возможности просто выбирать классы из библиотеки, которые, по вашему мнению, вам нужны; не было бы НИКАКОЙ гарантии, что те, которые вам нужны, будут работать.
Комментарии:
1. Возможно, мне не удалось разобраться, и я обновил свой вопрос