1. Введение
Создание программного проекта обычно состоит из таких задач, как загрузка зависимостей, размещение дополнительных jar-файлов в пути к классам, компиляция исходного кода в двоичный код, выполнение тестов, упаковка скомпилированного кода в развертываемые артефакты, такие как файлы JAR, WAR и ZIP, и развертывание этих артефактов. на сервер приложений или репозиторий.
Apache Maven автоматизирует эти задачи, сводя к минимуму риск ошибок людей при сборке программного обеспечения вручную и отделяя работу по компиляции и упаковке нашего кода от работы по его построению.
В этом руководстве мы собираемся изучить этот мощный инструмент для описания, создания и управления программными проектами Java с использованием центральной части информации — объектной модели проекта
(POM), которая написана на XML.
2. Зачем использовать Maven?
Ключевые особенности Maven:
- простая настройка проекта в соответствии с лучшими практиками: Maven пытается максимально избежать настройки, предоставляя шаблоны проекта (названные
архетипами
) - управление зависимостями: оно включает в себя автоматическое обновление, загрузку и проверку совместимости, а также отчеты о закрытии зависимостей (известные также как транзитивные зависимости)
- изоляция между зависимостями проекта и плагинами: с Maven зависимости проекта извлекаются из
репозиториев зависимостей
, в то время как любые зависимости плагинов извлекаются изрепозиториев плагинов,
что приводит к меньшему количеству конфликтов, когда плагины начинают загружать дополнительные зависимости - система центрального репозитория: зависимости проекта могут быть загружены из локальной файловой системы или общедоступных репозиториев, таких как Maven Central
Чтобы узнать, как установить Maven в вашей системе, ознакомьтесь с этим руководством на ForEach .
3. Объектная модель проекта
Конфигурация проекта Maven выполняется с помощью объектной модели проекта (POM)
, представленной файлом pom.xml
. POM
описывает проект , управляет зависимостями и настраивает плагины для сборки программного обеспечения.
POM также определяет отношения между модулями многомодульных
проектов. Давайте посмотрим на базовую структуру типичного файла POM :
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.foreach</groupId>
<artifactId>foreach</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>com.foreach</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.8.2</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
//...
</plugin>
</plugins>
</build>
</project>
Рассмотрим эти конструкции подробнее.
3.1. Идентификаторы проекта
Maven использует набор идентификаторов, также называемых координатами, для уникальной идентификации проекта и указания того, как должен быть упакован артефакт проекта:
groupId
— уникальное базовое имя компании или группы, создавшей проектArtiftId
— уникальное имя проекта.version
– версия проектаупаковка
— метод упаковки (например,WAR
/JAR
/ZIP
)
Первые три из них ( groupId:artifactId:version
) объединяются для формирования уникального идентификатора и представляют собой механизм, с помощью которого вы указываете, какие версии внешних библиотек (например, JAR) будут использоваться в вашем проекте.
3.2. Зависимости
Эти внешние библиотеки, которые использует проект, называются зависимостями. Функция управления зависимостями в Maven обеспечивает автоматическую загрузку этих библиотек из центрального репозитория, поэтому вам не нужно хранить их локально.
Это ключевая функция Maven, обеспечивающая следующие преимущества:
- использует меньше места для хранения за счет значительного сокращения количества загрузок из удаленных репозиториев
- ускоряет проверку проекта
- предоставляет эффективную платформу для обмена двоичными артефактами внутри вашей организации и за ее пределами без необходимости каждый раз создавать артефакты из исходного кода.
Чтобы объявить зависимость от внешней библиотеки, вам необходимо указать groupId, ArtiftId
и версию
библиотеки. Давайте рассмотрим пример:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.3.16</version>
</dependency>
Когда Maven обработает зависимости, он загрузит библиотеку Spring Core в ваш локальный репозиторий Maven.
3.3. Репозитории
Репозиторий в Maven используется для хранения артефактов сборки и зависимостей различных типов. Локальный репозиторий по умолчанию находится в папке .m2/repository
в домашнем каталоге пользователя.
Если артефакт или плагин доступны в локальном репозитории, Maven использует их. В противном случае он загружается из центрального репозитория и сохраняется в локальном репозитории. Центральным репозиторием по умолчанию является Maven Central .
Некоторые библиотеки, такие как сервер JBoss, недоступны в центральном репозитории, но доступны в альтернативном репозитории. Для этих библиотек вам необходимо указать URL-адрес альтернативного репозитория внутри файла pom.xml
:
<repositories>
<repository>
<id>JBoss repository</id>
<url>http://repository.jboss.org/nexus/content/groups/public/</url>
</repository>
</repositories>
Обратите внимание, что вы можете использовать несколько репозиториев в своих проектах.
3.4. Характеристики
Пользовательские свойства могут помочь упростить чтение и обслуживание файла pom.xml .
В классическом случае вы должны использовать настраиваемые свойства для определения версий зависимостей вашего проекта.
Свойства Maven являются заполнителями значений и доступны в любом месте pom.xml
с помощью нотации ${name}
, где name
— это свойство.
Давайте посмотрим пример:
<properties>
<spring.version>5.3.16</spring.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
</dependencies>
Теперь, если вы хотите обновить Spring до более новой версии, вам нужно только изменить значение внутри тега свойства <spring.version>
, и все зависимости, использующие это свойство в своих тегах <version>
, будут обновлены.
Свойства также часто используются для определения переменных пути сборки:
<properties>
<project.build.folder>${project.build.directory}/tmp/</project.build.folder>
</properties>
<plugin>
//...
<outputDirectory>${project.resources.build.folder}</outputDirectory>
//...
</plugin>
3.5. Строить
Раздел сборки
также является очень важным разделом Maven POM.
Он предоставляет информацию о цели
Maven по умолчанию , каталоге для скомпилированного проекта и окончательном имени приложения. Раздел сборки
по умолчанию выглядит так:
<build>
<defaultGoal>install</defaultGoal>
<directory>${basedir}/target</directory>
<finalName>${artifactId}-${version}</finalName>
<filters>
<filter>filters/filter1.properties</filter>
</filters>
//...
</build>
Выходная папка по умолчанию для скомпилированных артефактов называется target
, а окончательное имя упакованного артефакта состоит из артефактаId
и версии
, но вы можете изменить его в любое время.
3.6. Использование профилей
Еще одна важная особенность Maven — поддержка профилей.
Профиль в основном представляет
собой набор значений конфигурации. Используя профили
, вы можете настроить сборку для различных сред, таких как производство/тестирование/разработка:
<profiles>
<profile>
<id>production</id>
<build>
<plugins>
<plugin>
//...
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>development</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<build>
<plugins>
<plugin>
//...
</plugin>
</plugins>
</build>
</profile>
</profiles>
Как видно из приведенного выше примера, профиль по умолчанию — development
. Если вы хотите запустить производственный
профиль
, вы можете использовать следующую команду Maven:
mvn clean install -Pproduction
4. Жизненные циклы сборки Maven
Каждая сборка Maven следует определенному жизненному циклу
. Вы можете выполнить несколько целей
жизненного цикла
сборки , в том числе для компиляции
кода проекта, создания пакета
и установки
файла архива в локальном репозитории зависимостей Maven.
4.1. Фазы жизненного цикла
В следующем списке показаны наиболее важные этапы жизненного цикла
Maven :
validate
— проверяет правильность проектаcompile
— компилирует предоставленный исходный код в бинарные артефактыtest
— выполняет модульные тестыpackage
— упаковывает скомпилированный код в архивный файлIntegration-test
— выполняет дополнительные тесты, для которых требуется упаковкаVerify
— проверяет, действителен ли пакетinstall
— устанавливает файл пакета в локальный репозиторий Maven.deploy
— развертывает файл пакета на удаленном сервере или в репозитории.
4.2. Плагины
и цели
Плагин
Maven представляет собой набор из одной или нескольких целей
. Цели выполняются поэтапно, что помогает определить порядок, в котором цели
выполняются.
Богатый список плагинов, официально поддерживаемых Maven, доступен здесь . Также есть интересная статья о том, как собрать исполняемый JAR
-файл на ForEach с помощью различных плагинов.
Чтобы лучше понять, какие цели
и на каких этапах выполняются по умолчанию, взгляните на стандартные привязки жизненного цикла
Maven `` .
Чтобы пройти любой из вышеперечисленных этапов, нам просто нужно вызвать одну команду:
mvn <phase>
Например, mvn clean install
удалит ранее созданные файлы jar/war/zip и скомпилированные классы ( clean)
и выполнит все этапы, необходимые для установки нового архива ( install)
.
Обратите внимание, что цели
, предоставляемые плагинами
, могут быть связаны с разными этапами жизненного цикла
.
5. Ваш первый проект Maven
В этом разделе мы будем использовать функциональные возможности командной строки Maven для создания проекта Java.
5.1. Генерация простого Java-проекта
Чтобы создать простой проект Java, давайте запустим следующую команду:
mvn archetype:generate \
-DgroupId=com.foreach \
-DartifactId=foreach \
-DarchetypeArtifactId=maven-archetype-quickstart \
-DarchetypeVersion=1.4 \
-DinteractiveMode=false
GroupId — это
параметр, указывающий группу или отдельного человека, создавшего проект, который часто является обратным доменным именем компании. ArtifactId — это базовое
имя пакета, используемое в проекте, и мы используем стандартный архетип
. Здесь мы используем последнюю версию архетипа, чтобы убедиться, что наш проект создан с обновленной и последней структурой.
Поскольку мы не указали версию и тип упаковки, для них будут установлены значения по умолчанию — версия будет установлена на 1.0-SNAPSHOT,
а упаковка по умолчанию будет jar .
Если вы не знаете, какие параметры предоставить, вы всегда можете указатьinteractiveMode =
true ,
чтобы Maven запросил все необходимые параметры.
После выполнения команды у нас есть проект Java, содержащий класс App.java
, который представляет собой простую программу «Hello World», в папке src/main/java .
У нас также есть пример тестового класса в src/test/java
. pom.xml этого
проекта будет выглядеть примерно так:
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.foreach</groupId>
<artifactId>foreach</artifactId>
<version>1.0-SNAPSHOT</version>
<name>foreach</name>
<url>http://www.example.com</url>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
Как видите, зависимость JUnit
предоставляется по умолчанию.
5.2. Компиляция и упаковка проекта
Следующим шагом будет компиляция проекта:
mvn compile
Maven пройдет через все этапы жизненного цикла
, необходимые на этапе компиляции
для сборки исходных кодов проекта. Если вы хотите запустить только тестовую
фазу, вы можете использовать:
mvn test
Теперь давайте вызовем фазу пакета
,
которая создаст скомпилированный архивный jar
- файл:
mvn package
5.3. Выполнение приложения
Наконец, мы собираемся выполнить наш Java-проект с exec-maven-plugin
. Настроим необходимые плагины в pom.xml
:
<build>
<sourceDirectory>src</sourceDirectory>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.6.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>3.0.0</version>
<configuration>
<mainClass>com.foreach.java.App</mainClass>
</configuration>
</plugin>
</plugins>
</build>
Первый плагин, maven-compiler-plugin
, отвечает за компиляцию исходного кода с использованием Java версии 1.8. exec-maven-plugin
ищет mainClass в
нашем проекте.
Чтобы запустить приложение, мы запускаем следующую команду:
mvn exec:java
6. Заключение
В этой статье мы обсудили некоторые из наиболее популярных функций инструмента сборки Apache Maven.
Все примеры кода в ForEach созданы с использованием Maven, поэтому вы можете легко посетить наш веб- сайт проекта GitHub, чтобы увидеть различные конфигурации Maven.