предисловие
Как мы все знаем, maven — это, по сути, фреймворк для выполнения плагинов, и вся работа выполняется через плагины. Включая аналогичную установку, очистку, развертывание и компиляцию, которые мы используем каждый день. . . Эти команды, по сути, все плагины maven один за другим внизу.
Как разработать собственный плагин
1. Соглашения об именах для плагинов maven
Прежде чем писать проект, первым делом нужно определиться с названием. Плагин maven не является исключением. Он имеет свой собственный набор соглашений об именах. Но спецификация очень проста, ее можно резюмировать одним предложением, ** формат официального имени плагина — maven-xxx-plugin, а неофициальное имя плагина — xxx-maven-plugin. ** Звучит знакомо? Да, существуют похожие спецификации для именования стартеров Spring Boot.
Хорошо, давайте назовем наш первый проект плагина maven demo-maven-plugin.
2. Создать проект
Ну, судя по названию, следующим шагом будет создание проекта. Если воспользоваться идеей, то создать очень удобно можно по следующим шагам:
2.1 Выберите org.apache.maven.archetypes:maven-archetype-mojo, чтобы создать проект скелета.
- Выберите Создать новый проект
- Выберите создание через maven
- Установите флажок Создать из архетипа, чтобы создать через скелет проекта.
- Выберите org.apache.maven.archetypes:maven-archetype-mojo.
- Нажмите "Далее
2.2 Введите название проекта с первого шага
Нажмите "Далее
2.3 Нажмите «Готово», чтобы завершить создание проекта.
2.4 Анализ файлов проекта
Структура проекта
Вы можете видеть, что сгенерированный проект является структурой нашего самого распространенного проекта maven, и сгенерированных файлов очень мало, один файл pom.xml, один файл MyMojo, кратко представим эти два файла.
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>cn.coder4j.study.example</groupId>
<artifactId>demo-maven-plugin</artifactId>
<packaging>maven-plugin</packaging>
<version>1.0-SNAPSHOT</version>
<name>demo-mavne-plugin Maven Mojo</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-plugin-api</artifactId>
<version>2.0</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
В первом сгенерированном элементе POM.xml два проекта автоматически полагаются, один является Maven-Plugin-API, который является основным пакетом, который разрабатывает плагин Maven, должен зависеть от. Другой - это пакет Junit, используемый в тестировании подразделения. Эти двое не имеют ничего общего внимания, я действительно хочу обратить внимание на упаковку этого проекта, обычно я уже столкнулся с упаковкой - это банка, война, пом, вот специально Maven-плагин.
MyMojo.java
package cn.coder4j.study.example;
/*
* Copyright 2001-2005 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
/**
* Goal which touches a timestamp file.
*
* @goal touch
*
* @phase process-sources
*/
public class MyMojo
extends AbstractMojo
{
/**
* Location of the file.
* @parameter expression="${project.build.directory}"
* @required
*/
private File outputDirectory;
public void execute()
throws MojoExecutionException
{
File f = outputDirectory;
if ( !f.exists() )
{
f.mkdirs();
}
File touch = new File( f, "touch.txt" );
FileWriter w = null;
try
{
w = new FileWriter( touch );
w.write( "touch.txt" );
}
catch ( IOException e )
{
throw new MojoExecutionException( "Error creating file " + touch, e );
}
finally
{
if ( w != null )
{
try
{
w.close();
}
catch ( IOException e )
{
// ignore
}
}
}
}
}
Первый сгенерированный класс наследует абстрактный класс AbstractMojo. Вот требования к спецификации плагина maven. Плагин maven должен наследовать AbstractMojo и реализовать свой метод выполнения.
Кроме того, вы можете видеть, что классы и методы используют много тегов. Обратите внимание, что теги не являются аннотациями. Аннотации помечаются напрямую, а теги находятся внутри комментариев к документации.
Среди них роль тега @goal заключается в указании имени плагина, например mvn clean, который обычно используется у нас, это его @goal.
И @фаза — это цикл генерации выполнения плагина привязки.Например, если вы выполняете привязку в цикле очистки, ваш плагин будет автоматически запускаться при выполнении очистки.
@parameter используется для указания параметров плагина.
Дети у вас есть много вопросительных знаков? Обведите эту вещь, написанную в документе Annotation Factory внутри, но удобство состоит в том, чтобы облегчить его неправильно, нет неправильного синтаксиса ошибки, когда нет синтаксиса для написания советов, почему бы не просто использовать его как аннотации? Причина в том, что Java Annotation только после JDK1.5, но время еще не достигнуто Maven этот синтаксис. Так к дороге идет черным, он вернулся к этому историческому обременению? Конечно, нет, мы скажем, что за решением. Кроме того, хотя такой подход не рекомендуется, но некоторые из классических плагинов Maven из-за времени завершения ранее эти теги, знакомые для понимания кода также могут помочь.
3. Разрабатывайте плагины
3.1 Код не перемещается, опирайтесь на первый pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>cn.coder4j.study.example</groupId>
<artifactId>demo-maven-plugin</artifactId>
<packaging>maven-plugin</packaging>
<version>1.0-SNAPSHOT</version>
<name>demo-mavne-plugin Maven Mojo</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-plugin-api</artifactId>
<version>3.5.2</version>
</dependency>
<dependency>
<groupId>org.apache.maven.plugin-tools</groupId>
<artifactId>maven-plugin-annotations</artifactId>
<version>3.5.2</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-plugin-plugin</artifactId>
<version>3.5.2</version>
</plugin>
</plugins>
</build>
</project>
По сравнению с файлом pom.xml по умолчанию мы внесли следующие изменения:
- Обновите версию плагина maven-plugin-api до 3.5.2. Родной 2.0 просто слишком стар.
- Добавьте зависимость maven-plugin-annotations, помните тег, упомянутый выше? С помощью этой зависимости вы можете напрямую использовать аннотацию
- Добавьте зависимость плагина maven-plugin-plugin. Основная причина добавления этой зависимости — скомпилировать и передать в jdk1.8, иначе будет сообщено об ошибке
3.2 DemoMojo.java
/*
*
* * *
* * * blog.coder4j.cn
* * * Copyright (C) 2016-2020 All Rights Reserved.
* *
*
*/
package cn.coder4j.study.example;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
/**
* @author buhao
* @version DemoMojo.java, v 0.1 2020-03-30 22:51 buhao
*/
@Mojo(name = "hello")
public class DemoMojo extends AbstractMojo {
@Parameter(name = "name", defaultValue = "kiwi")
private String name;
public void execute() throws MojoExecutionException, MojoFailureException {
getLog().info("hello " + name);
}
}
Во-первых, как сгенерированный класс, наши классы должны унаследовать абстрактные Mojo и добиться своего метода execute, а метод execute на самом деле находится входным классом этого плагина.
В примере кода есть две важные аннотации: одна @Mojo , которая в основном используется для определения информации, связанной с плагином, что эквивалентно @goal, упомянутому выше, где атрибут name используется для указания имени плагина, похоже на чистый.
Еще одна важная аннотация @Parameter используется для указания параметров, используемых подключаемым модулем при его работе, где name — это имя параметра, а defaultValue — значение по умолчанию, как следует из названия, то есть значение, используемое, когда пользователь не устанавливает Это.
Подробные плагины и их функции следующие:
import org.apache.maven.execution.MavenSession;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecution;
import org.apache.maven.plugin.descriptor.PluginDescriptor;
import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.Execute;
import org.apache.maven.plugins.annotations.InstantiationStrategy;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.plugins.annotations.ResolutionScope;
import org.apache.maven.project.MavenProject;
import org.apache.maven.settings.Settings;
// 此Mojo对应的目标的名称
@Mojo( name = "<goal-name>",
aggregator = <false|true>,
configurator = "<role hint>",
// 执行策略
executionStrategy = "<once-per-session|always>",
inheritByDefault = <true|false>,
// 实例化策略
instantiationStrategy = InstantiationStrategy.<strategy>,
// 如果用户没有在POM中明确设置此Mojo绑定到的phase,那么绑定一个MojoExecution到那个phase
defaultPhase = LifecyclePhase.<phase>,
requiresDependencyResolution = ResolutionScope.<scope>,
requiresDependencyCollection = ResolutionScope.<scope>,
// 提示此Mojo需要被直接调用(而非绑定到生命周期阶段)
requiresDirectInvocation = <false|true>,
// 提示此Mojo不能在离线模式下运行
requiresOnline = <false|true>,
// 提示此Mojo必须在一个Maven项目内运行
requiresProject = <true|false>,
// 提示此Mojo是否线程安全,线程安全的Mojo支持在并行构建中被并发的调用
threadSafe = <false|true> ) // (since Maven 3.0)
// 何时执行此Mojo
@Execute( goal = "<goal-name>", // 如果提供goal,则隔离执行此Mojo
phase = LifecyclePhase.<phase>, // 在此生命周期阶段自动执行此Mojo
lifecycle = "<lifecycle-id>" ) // 在此生命周期中执行此Mojo
public class MyMojo
extends AbstractMojo
{
@Parameter( name = "parameter",
// 在POM中可使用别名来配置参数
alias = "myAlias",
property = "a.property",
defaultValue = "an expression, possibly with ${variables}",
readonly = <false|true>,
required = <false|true> )
private String parameter;
@Component( role = MyComponentExtension.class,
hint = "..." )
private MyComponent component;
@Parameter( defaultValue = "${session}", readonly = true )
private MavenSession session;
@Parameter( defaultValue = "${project}", readonly = true )
private MavenProject project;
@Parameter( defaultValue = "${mojoExecution}", readonly = true )
private MojoExecution mojo;
@Parameter( defaultValue = "${plugin}", readonly = true )
private PluginDescriptor plugin;
@Parameter( defaultValue = "${settings}", readonly = true )
private Settings settings;
@Parameter( defaultValue = "${project.basedir}", readonly = true )
private File basedir;
@Parameter( defaultValue = "${project.build.directory}", readonly = true )
private File target;
public void execute()
{
}
}
Вернемся к примеру, наш плагин очень простой, выводит hello xxx в соответствии с конфигурацией и выводит hello kiwi, если конфигурации нет. Когда мы пишем плагины, мы, конечно, не пишем их так, но с помощью этой демонстрации вы усвоили большую часть знаний о плагинах maven и можете сами создавать очень интересные плагины.
4. Используйте плагины
Прежде всего, после того, как наш код написан выше, мы должны его установить, иначе другие проекты не могут от него напрямую зависеть.Если вы хотите использовать его для других, вам нужно загрузить его в репозиторий maven.
4.1 Плагин зависимостей
<build>
<plugins>
<plugin>
<groupId>cn.coder4j.study.example</groupId>
<artifactId>demo-maven-plugin</artifactId>
<version>1.0-SNAPSHOT</version>
</plugin>
</plugins>
</build>
В проекте, где мы хотим использовать плагин, добавьте приведенную выше конфигурацию, где информация GAV нашего плагина используется в плагине.
4.2 Запустите плагин
Если приведенная выше конфигурация верна, то в Maven с правой стороны идеи будет демо (согласно названию вашего проекта плагина) в разделе Плагины настроенного вами проекта, и там будет демо : привет в демке, среди которых эта демка соответствует названию вашего проекта плагина, а привет соответствует названию вашего плагина, которое есть в @Mojo.
Хорошо, давайте дважды щелкнем, demo:hello, будет выведен следующий лог:
На этом наш первый плагин Maven готов.
4.3 Параметры конфигурации
Как вы, возможно, помните, мы также указали атрибут имени, когда писали DemoMojo, и указали для него параметр, как его использовать. Просто добавьте тег конфигурации под зависимыми плагинами.
<build>
<plugins>
<plugin>
<groupId>cn.coder4j.study.example</groupId>
<artifactId>demo-maven-plugin</artifactId>
<version>1.0-SNAPSHOT</version>
<configuration>
<name>tom</name>
</configuration>
</plugin>
</plugins>
</build>
Теги в теге конфигурации соответствуют именам параметров, которые вы определяете, и идея также имеет подсказки по синтаксису, что очень приятно.
Хорошо, давайте запустим его снова, и результат будет следующим:
Хорошо, все готово.
разное
Ссылка на ссылку
Исходный код проекта
Из-за ограниченного места разместить все коды невозможно, если у вас возникнут проблемы, вы можете перейти наgithubСм. исходный код выше.