3、Maven高级:自定义插件开发、Archetype脚手架生成、Nexus私服搭建与部署
好,咱们进入Maven的高级部分。说实话,很多同学用了好几年Maven,也就停留在配置依赖、写写pom.xml的阶段。但真正到了企业级项目里,你会发现光会这些远远不够。今天我要讲的这三个主题——自定义插件、Archetype脚手架、Nexus私服——说白了,就是让你从Maven的“使用者”变成“掌控者”。
3.1 自定义Maven插件开发
先问个问题:你有没有遇到过这样的场景?每次发布前,都要手动改版本号、打时间戳、生成API文档。重复劳动不说,还容易出错。我当时在一个金融项目里,就因为手动改版本号漏了一个地方,导致线上包和代码对不上,排查了整整一个下午。
嗯,这时候你就需要自定义插件了。Maven插件本质上就是一个Mojo(Maven Old Java Object),继承AbstractMojo类,实现execute()方法就行。
3.1.1 快速上手:写一个打印时间的插件
我习惯先从一个最简单的例子入手。创建一个maven项目,pom.xml里加上maven-plugin的打包方式:
<packaging>maven-plugin</packaging>
然后引入核心依赖:
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-plugin-api</artifactId>
<version>3.8.1</version>
</dependency>
<dependency>
<groupId>org.apache.maven.plugin-tools</groupId>
<artifactId>maven-plugin-annotations</artifactId>
<version>3.6.0</version>
<scope>provided</scope>
</dependency>
接下来写Mojo类:
@Mojo(name = "showtime")
public class ShowTimeMojo extends AbstractMojo {
@Parameter(property = "showtime.format", defaultValue = "yyyy-MM-dd HH:mm:ss")
private String format;
public void execute() throws MojoExecutionException {
SimpleDateFormat sdf = new SimpleDateFormat(format);
getLog().info("当前时间:" + sdf.format(new Date()));
}
}
执行 mvn com.example:my-plugin:showtime 就能看到输出了。你看,是不是很简单?
@Parameter 注解暴露配置项。这样用户就能在pom.xml里灵活配置,不用改代码。
3.1.2 实战:自动化版本号插件
我在项目中遇到过最头疼的事,就是多模块项目的版本号管理。几十个模块,每次发版都要逐个改。后来我写了个插件,自动读取Git标签来生成版本号。
@Mojo(name = "auto-version", requiresProject = true)
public class AutoVersionMojo extends AbstractMojo {
@Parameter(defaultValue = "${project.version}")
private String version;
public void execute() throws MojoExecutionException {
// 读取Git标签
String gitTag = getGitTag();
if (gitTag != null) {
// 自动替换版本号
MavenProject project = (MavenProject) getPluginContext().get("project");
project.setVersion(gitTag);
getLog().info("版本号已自动设置为:" + gitTag);
}
}
}
project.setVersion() 就够了,改文件会导致版本控制混乱。
3.2 Archetype脚手架生成
每次新建项目都要重复搭架子:建目录、写pom.xml、配日志框架、加单元测试依赖……烦不烦?反正我是烦了。Archetype就是解决这个问题的。
3.2.1 从现有项目生成Archetype
我推荐一个最快的方法:找一个你满意的项目,直接用它生成Archetype。
mvn archetype:create-from-project
这个命令会在 target/generated-sources/archetype 下生成脚手架项目。你只需要调整 archetype-metadata.xml 文件,定义哪些文件是模板、哪些是静态资源。
3.2.2 自定义模板变量
举个例子,你的项目里有个 Application.java,里面引用了包名。你可以把它改成模板文件:
package ${package};
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class ${className}Application {
public static void main(String[] args) {
SpringApplication.run(${className}Application.class, args);
}
}
然后在 archetype-metadata.xml 里声明:
<requiredProperties>
<requiredProperty key="className">
<defaultValue>Demo</defaultValue>
</requiredProperty>
</requiredProperties>
核心思路: Archetype的本质就是“模板引擎 + 文件复制”。你定义好变量,Maven在生成项目时自动替换。说白了,就是把你手动做的事情自动化了。
3.3 Nexus私服搭建与部署
说到私服,我记得刚入行时在一家小公司,团队就五六个人,连私服都没有。每次加依赖都要从中央仓库下载,慢得要命。更坑的是,有一次中央仓库挂了,整个团队干等了一上午。
后来我搭了Nexus,世界清净了。
3.3.1 搭建步骤(Docker版)
现在搭私服太简单了,用Docker几分钟搞定:
docker run -d -p 8081:8081 --name nexus sonatype/nexus3
启动后访问 http://localhost:8081,默认管理员账号是 admin,密码在容器里的 /nexus-data/admin.password 文件中。
3.3.2 仓库类型与配置
Nexus有三种核心仓库类型,我整理了个表格:
| 仓库类型 | 用途 | 我常用的场景 |
|---|---|---|
| proxy | 代理中央仓库 | 缓存外部依赖,加速构建 |
| hosted | 存放私有构件 | 公司内部jar包、第三方商业库 |
| group | 聚合多个仓库 | 一个URL访问所有仓库 |
配置好之后,在项目的 pom.xml 里加上:
<repositories>
<repository>
<id>nexus</id>
<url>http://你的私服地址:8081/repository/maven-public/</url>
</repository>
</repositories>
3.3.3 部署构件到私服
部署到私服需要配置 settings.xml 里的认证信息:
<servers>
<server>
<id>nexus-releases</id>
<username>admin</username>
<password>你的密码</password>
</server>
</servers>
然后在pom.xml里配置发布地址:
<distributionManagement>
<repository>
<id>nexus-releases</id>
<url>http://私服地址:8081/repository/maven-releases/</url>
</repository>
<snapshotRepository>
<id>nexus-snapshots</id>
<url>http://私服地址:8081/repository/maven-snapshots/</url>
</snapshotRepository>
</distributionManagement>
执行 mvn deploy,你的构件就上传到私服了。其他同事只需要配置好仓库地址,就能直接引用。
好了,这三个技能你掌握了,基本上Maven这块就没什么能难住你的了。从写插件自动化重复工作,到用Archetype统一项目结构,再到搭私服管理构件——这一套组合拳打下来,你团队的构建效率至少提升50%。