Кодогенерация с помощью Maven Archetype
Понадобилось мне по работе для массового перехода проекта с одной структуры на другую придумать вариант как упростить создание нового проекта.
В принципе, для этого и был придуман Maven Archetype.
Стандартизация и единообразие
Maven Archetype позволяет установить стандартную структуру для всех проектов: то есть все проекты будут иметь одинаковую организацию директорий, конфигурационные файлы и базовые зависимости. Благодаря этому новые члены команды могут легко погружаться в любой проект, так как все они будут выглядеть практически одинаково. Это снижает время обучения и упрощает управление проектами.
Экономия времени и усилий
С использованием Archetype можно быстро создать целый проект с нужной настройкой и структурой каталогов. Не нужно больше вручную настраивать pom.xml, создавать стандартные структуры папок или настраивать основные зависимости. Всё создаётся автоматически, что позволяет сразу приступить к написанию кода, избегая рутинных операций.
Лучшая поддержка и расширяемость
Проекты с использованием Maven Archetype легче поддерживать, расширять и масштабировать. Стандартная структура и настройки облегчают обновление зависимостей и внесение изменений для новых проектов. Можно создавать собственные архетипы для уникальных потребностей проекта, чтобы каждый новый проект автоматически включал специфические настройки и используемые практики.
Легкость интеграции с CI/CD
Maven прекрасно интегрируется с популярными системами непрерывной интеграции и доставки (CI/CD), такими как Jenkins, GitLab CI, CircleCI и так далее. Используя стандартизированные Maven Archetypes, можно легко создавать проекты, полностью готовые к интеграции с вашими CI/CD конвейерами, посредством добавляения необходимых файлов. Это ускоряет процесс выпуска и повышения качества за счет автоматизации тестирования и деплоя.
Снижение количества ошибок
Благодаря стандартизированным шаблонам проектов, можно избежать типичных ошибок, которые могут возникнуть при ручной настройке новых проектов. Все зависимости и конфигурации уже протестированы и проверены, что минимизирует вероятность багов и конфигурационных ошибок.
Создание собственного архетипа
Для создания собственного архетипа можно воспользовать уже готовым архетипом :)
mvn archetype:generate -DarchetypeArtifactId=maven-archetype-archetype -DarchetypeVersion=1.4 -DgroupId=ru.maksimvoloshin.maven -DartifactId=archetype -Dversion=1.0.0
Заполнив необходимые поля, мы на выходе получим необходимую структуру каталогов:
Всё, что нам потребуется в будущем коде – находится в папке src/main/resources/META-INF/maven
. Конкретно – файл archetype-metadata-xml:
<?xml version="1.0" encoding="UTF-8"?>
<archetype-descriptor xmlns="http://maven.apache.org/plugins/maven-archetype-plugin/archetype-descriptor/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-archetype-plugin/archetype-descriptor/1.0.0 http://maven.apache.org/xsd/archetype-descriptor-1.0.0.xsd"
name="${artifactId}">
<fileSets>
<fileSet filtered="true" packaged="true">
<directory>src/main/java</directory>
</fileSet>
<fileSet filtered="true" packaged="true">
<directory>src/test/java</directory>
</fileSet>
</fileSets>
</archetype-descriptor>
Здесь у нас основной корневой элемент, который содержит в себе набор правил, как обрабатывать файлы. Поскольку Maven
достаточно косноязычен (но прост и быстр, в целом), приходится каждую папку описывать отдельно.
Элемент fileSets содержит в себе fileSet’ы, которые мы будем переносить при генерации. Тэг fileSet имеет два аттрибута: filtered и packaged
- filtered – указывает, нужно ли при переносе использовать Velocity движок. То есть мы можем писать условия и вообще творить магию, используя Apache Velocity.
- packaged – указывает, надо ли упаковать это в директорию указанного пакета (то есть в каталоги
Как видно на скриншоте, часть файлов мне нужно исключить (потому что в них используется знак $). Поэтому сначала я копирую то, что нужно скопировать с фильтрацией и исключаю. А потом наоборот.
А вот пример обработки, используя Apache Velocity:
Также в archetype-metadata.xml
есть полезный тэг requiredProperties
, содержащий в себе requiredProperty
, которые можно стребовать при генерации или задать их по умолчанию:
В целом, для каких-то простых вещей, этого хватает. Но я для себя открыл ещё один лайфхак. Maven
поддерживает пост обработку после генерации архетипа. Делается это через добавление файла archetype-post-generate.groovy
в директорию src/main/resources/META-INF
import java.nio.file.Path
import java.nio.file.Paths
// путь, куда сгенерируется проект
Path projectPath = Paths.get(request.outputDirectory, request.artifactId)
// проперти, заданные при создании архетипа
Properties properties = request.properties
// Имя пакета
String packageName = properties.get('package')
// конвертируем имя пакета в путь
String packagePath = packageName.replace('.', '/')
// настройки
boolean withParam = Boolean.valueOf(properties.get('withParam') as String)
Используя этот файл, можно создать, удалить, изменить уже существующие файлы под какие-то условия. Например, withParam
задаётся через requiredProperty
(предполагается, что он будет типа boolean) и дальше мы можем что-то сделать, опираясь на это условие.
После того, как всё готово, просто требуется выполнить mvn install
для отправки в артефакта в локальный репозиторий. После чего, он будет доступен для Maven
. Также, при отправке в удалённый репозиторий, потребуется обновления (автоматическое или ручное) файла archetype-catalog.xml
, чтобы Maven
увидел этот артефакт.
Ну и не забываем, что в центральном репозитории Maven
уже лежит свыше 3000 готовых артефактов :)
Последние комменатрии