构建¶
Java 程序的构建过程一般是:编译、测试、打包。
如果文件比较少,我们可以使用以下命令手动构建
jdb # 调试器,用于开发阶段的运行调试
javac # 编译器,把 .java 源码编译为 .class 字节码
java # 启动 JVM 执行编译后的代码
jar # 把一组 .class 文件打包成 .jar 包,便于发布
# 查看编译器版本
javac -version
'
javac 22.0.2
'
# 查看虚拟机版本
java -version
'
java 22.0.2 2024-07-16
Java(TM) SE Runtime Environment (build 22.0.2+9-70)
Java HotSpot(TM) 64-Bit Server VM (build 22.0.2+9-70, mixed mode, sharing)
'
但当工程越来越大,文件越来越多,这些机械重复的工作就需要交给工具来完成了:
- Ant 与 Makefile 比较像,定义任务,规定依赖,执行任务,缺点是没办法管理依赖
- Maven 提出仓库的概念,缺点是使用 xml 语法不简洁,无法自定义任务
- Gradle 继承 Maven 和 Ant 的优点,可以用仓库管理依赖也能自定义任务,
build.gradle基于脚本语言 Groovy
Maven¶
Java 项目构建和依赖管理工具,可以自动化构建、测试、打包和部署项目
idea、ecplise 等不同工具默认的构建格式要求不同,所以统一选择使用 maven 构建可以基于任何工具开发
官网 https://maven.apache.org/ 下载最新的 apache-maven-<version>-bin.tar.gz 文件解压到某处,比如 /usr/local/,然后配置环境变量
export M2_HOME=/usr/local/apache-maven-3.x.x
export PATH=$PATH:$M2_HOME/bin
mvn -v
项目结构
path/
project1/
project2/
project3/
├── pom.xml # Maven 配置文件
├── src
│ ├── main
│ │ ├── java # Java 源代码目录
│ │ └── com/example/myapp/ # 开发者代码主目录,主类(入口)Main.java
│ │ controller
│ │ service
│ │ dao
│ │ model
│ │ ├── resources # 存放静态资源、配置文件等
│ │ log4j.properties
│ │ spring-mybatis.xml
│ │ static/
│ │ css/
│ │ js/
│ │ images/
│ │ ├── webapp # Java Web 标准结构,不能乱改
│ │ └── WEB-INF
│ │ └── web.xml
│ └── test
│ └── java # 测试源码目录
│ └── resources # 测试资源目录
├── target # 所有编译、打包生成的文件会放在这里
│ ├── classes
│ │ ├── com/example/ # Java 编译后的字节码文件,比如 Main.class
│ └── test-classes
配置文件¶
settings.xml是特定用户/环境的配置,例如安全凭证、本地仓库位置、代理、镜像等,不能提交到 git- 用户级别:位于
$~/.m2/settings.xml,影响当前用户 - 全局级别,位于
${maven.home}/conf/settings.xml
- 用户级别:位于
pom.xml是项目的配置,例如项目 GAV、依赖、插件、构建生命周期等
依赖管理¶
依赖包哪里去找?
- https://search.maven.org/ Maven 核心贡献者 Sonatype 团队维护
- https://mvnrepository.com/ 社区聚合,更丰富
<?xml version="1.0" encoding="UTF-8"?>
<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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<!-- 一个 Maven 工程由 GAV 三个字段唯一标识一个依赖 groupId:artifactId:version -->
<!-- com.example:demo:1.0-SNAPSHOT -->
<groupId>com.example</groupId> <!-- 最多4级:com.{公司}.业务线.子业务线 -->
<artifactId>demo</artifactId> <!-- 单体项目可以随便起,微服务一般格式:产品线名-模块名,通常跟项目名保持一致 -->
<version>1.0-SNAPSHOT</version> <!-- 通常3级:主版本号.次版本号.修订号,一般工具会默认配置 -->
<!-- Packaging 属性指示将项目打包为什么类型的文件,比如idea会据此识别Maven项目类型 -->
<packaging>war</packaging>
<!--
jar 代表普通的 Java 工程,打包后是 .jar 结尾的文件,不写的时候默认就是这个
war 代表 Java Web 工程,打包以后是 .war 结尾的文件
pom 代表不会打包,用来做继承的父工程
-->
<!-- 固定JDK版本,防止同一个项目的不同的开发者各自使用不同版本的JDK -->
<properties>
<maven.compiler.source>17</maven.compiler.source> <!-- 表示Java编译器读取的源码版本 -->
<maven.compiler.target>17</maven.compiler.target> <!-- 表示Java编译器编译的Class版本 -->
<!-- maven.compiler.release 使用的JDK版本 -->
<!-- 还可以声明一些自定义变量,然后在其他位置引用:${jackson.version} -->
<xxx.yy>aaa</xxx.yy>
</properties>
<!-- 声明依赖,Maven会自动下载这个依赖包并把它放到classpath中 -->
<!-- scope 可选属性,限定依赖的作用域
compile 默认,可在 main, test, 打包和运行时使用
test 只在 test 中使用
runtime 只在打包和运行时使用,比如使用反射的时候
provided main和test中用,运行时不用,比如 servlet
-->
<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>2.0.16</version>
</dependency>
<dependency>
...
</dependency>
</dependencies>
<!-- 导入插件 -->
<build>
<plugin>
...gav...
</plugin>
</build>
</project>
构建¶
主要分清理、构建、报告三个周期,同一周期中后面的命令会自动触发前面的命令,比如 mvn package 会自动先触发 compile 和 test
# 清理周期
mvn clean # 清理上一次构建的产物,即删除 target 文件
# 构建周期
mvn compile # 编译项目,生成 target 文件
mvn test # 执行单元测试
mvn package # 打包项目,生成 artifact(jar/war等)
# 部署,必须是 jar 包形式
mvn install # 安装到本地 maven 仓库,位置:~/.m2/respository/
mvn deploy # 部署到远程 maven 仓库,仓库信息配置在 pom.xml 或 settings.xml 中
# 报告周期
mvn site # 生成项目依赖信息的展示页面,没啥用
命令可以连在一起写,所以常用的命令是:
- 打包:
mvn clean package - 重新编译:
mvn clean compile - 本地部署:
mvn clean install
