项目简介
Apache Maven是Apache软件基金会开发的项目管理和构建自动化工具,主要用于Java项目,也可用于C#、Ruby、Scala等语言。Maven基于项目对象模型(POM)的概念,通过一个XML文件来描述项目的构建、依赖关系和文档。
Maven最初由Jason van Zyl创建,旨在简化Jakarta Turbine项目的构建过程。它提供了一个标准的项目布局、一个标准的构建生命周期和一个依赖管理系统,极大地简化了Java项目的开发和维护。
主要特性
- 标准化项目结构:提供一致的项目布局
- 依赖管理:自动下载和管理项目依赖
- 构建生命周期:标准化的构建过程
- 插件架构:丰富的插件生态系统
- 中央仓库:全球最大的Java库仓库
- 多模块支持:管理大型项目的多个模块
项目原理
POM(项目对象模型)
POM是Maven的核心概念,包含项目信息和配置:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| <?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> <groupId>com.example</groupId> <artifactId>my-project</artifactId> <version>1.0.0</version> <packaging>jar</packaging> <name>My Project</name> <description>示例项目</description> <properties> <maven.compiler.source>11</maven.compiler.source> <maven.compiler.target>11</maven.compiler.target> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> </dependencies> <build> </build> </project>
|
标准目录结构
1 2 3 4 5 6 7 8 9 10 11 12
| project/ ├── pom.xml ├── src/ │ ├── main/ │ │ ├── java/ # 主要Java源码 │ │ ├── resources/ # 主要资源文件 │ │ └── webapp/ # Web应用资源(对于WAR项目) │ └── test/ │ ├── java/ # 测试Java源码 │ └── resources/ # 测试资源文件 ├── target/ # 编译输出目录 └── README.md
|
构建生命周期
Maven定义了三个内置的构建生命周期:
Default生命周期:
- validate - 验证项目正确性
- compile - 编译源代码
- test - 运行单元测试
- package - 打包成JAR/WAR
- verify - 验证包的有效性
- install - 安装到本地仓库
- deploy - 部署到远程仓库
Clean生命周期:
- pre-clean - 清理前执行
- clean - 清理构建输出
- post-clean - 清理后执行
Site生命周期:
- pre-site - 生成站点前执行
- site - 生成项目站点
- post-site - 生成站点后执行
- site-deploy - 部署站点
使用场景
1. Java项目构建
标准化Java项目的编译、测试、打包和部署流程。
2. 依赖管理
自动管理第三方库的下载、版本控制和传递依赖。
3. 多模块项目
管理大型企业级应用的多个子模块。
4. 持续集成
与Jenkins、GitLab CI等CI/CD工具集成,实现自动化构建。
5. 项目文档生成
自动生成项目文档、API文档和测试报告。
具体案例
案例1:Spring Boot项目配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
| <?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> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.7.0</version> <relativePath/> </parent> <groupId>com.example</groupId> <artifactId>spring-boot-demo</artifactId> <version>1.0.0</version> <packaging>jar</packaging> <name>Spring Boot Demo</name> <description>Spring Boot示例项目</description> <properties> <java.version>11</java.version> <mysql.version>8.0.29</mysql.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>${mysql.version}</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>${java.version}</source> <target>${java.version}</target> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <configuration> <skipTests>false</skipTests> </configuration> </plugin> </plugins> </build> </project>
|
案例2:多模块项目结构
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
| <?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> <groupId>com.example</groupId> <artifactId>parent-project</artifactId> <version>1.0.0</version> <packaging>pom</packaging> <name>Parent Project</name> <modules> <module>common</module> <module>service</module> <module>web</module> </modules> <properties> <maven.compiler.source>11</maven.compiler.source> <maven.compiler.target>11</maven.compiler.target> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <spring.version>5.3.21</spring.version> <junit.version>5.8.2</junit.version> </properties> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-framework-bom</artifactId> <version>${spring.version}</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter</artifactId> <version>${junit.version}</version> <scope>test</scope> </dependency> </dependencies> </dependencyManagement> <build> <pluginManagement> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.10.1</version> </plugin> </plugins> </pluginManagement> </build> </project>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| <?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> <parent> <groupId>com.example</groupId> <artifactId>parent-project</artifactId> <version>1.0.0</version> </parent> <artifactId>common</artifactId> <packaging>jar</packaging> <name>Common Module</name> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> </dependency> <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter</artifactId> <scope>test</scope> </dependency> </dependencies> </project>
|
案例3:自定义插件开发
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| <project> <modelVersion>4.0.0</modelVersion> <groupId>com.example</groupId> <artifactId>code-generator-maven-plugin</artifactId> <version>1.0.0</version> <packaging>maven-plugin</packaging> <dependencies> <dependency> <groupId>org.apache.maven</groupId> <artifactId>maven-plugin-api</artifactId> <version>3.8.6</version> </dependency> <dependency> <groupId>org.apache.maven.plugin-tools</groupId> <artifactId>maven-plugin-annotations</artifactId> <version>3.6.4</version> <scope>provided</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-plugin-plugin</artifactId> <version>3.6.4</version> </plugin> </plugins> </build> </project>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
| @Mojo(name = "generate", defaultPhase = LifecyclePhase.GENERATE_SOURCES) public class CodeGeneratorMojo extends AbstractMojo { @Parameter(defaultValue = "${project.build.directory}/generated-sources") private File outputDirectory; @Parameter(required = true) private String templatePath; @Parameter(required = true) private String packageName; @Component private MavenProject project; public void execute() throws MojoExecutionException { getLog().info("开始生成代码..."); try { if (!outputDirectory.exists()) { outputDirectory.mkdirs(); } generateCode(); project.addCompileSourceRoot(outputDirectory.getAbsolutePath()); getLog().info("代码生成完成"); } catch (Exception e) { throw new MojoExecutionException("代码生成失败", e); } } private void generateCode() throws IOException { File packageDir = new File(outputDirectory, packageName.replace('.', '/')); packageDir.mkdirs(); File javaFile = new File(packageDir, "GeneratedClass.java"); try (FileWriter writer = new FileWriter(javaFile)) { writer.write(String.format( "package %s;\n\n" + "public class GeneratedClass {\n" + " public void hello() {\n" + " System.out.println(\"Hello from generated code!\");\n" + " }\n" + "}\n", packageName)); } } }
|
案例4:高级配置示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
| <project> <properties> <spring.version>5.3.21</spring.version> <jackson.version>2.13.3</jackson.version> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> </properties> <profiles> <profile> <id>dev</id> <activation> <activeByDefault>true</activeByDefault> </activation> <properties> <env>dev</env> <database.url>jdbc:mysql://localhost:3306/dev_db</database.url> </properties> </profile> <profile> <id>prod</id> <properties> <env>prod</env> <database.url>jdbc:mysql://prod-server:3306/prod_db</database.url> </properties> </profile> </profiles> <build> <resources> <resource> <directory>src/main/resources</directory> <filtering>true</filtering> <includes> <include>**/*.properties</include> <include>**/*.yml</include> </includes> </resource> </resources> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-resources-plugin</artifactId> <version>3.2.0</version> <configuration> <encoding>UTF-8</encoding> </configuration> </plugin> <plugin> <groupId>org.jacoco</groupId> <artifactId>jacoco-maven-plugin</artifactId> <version>0.8.7</version> <executions> <execution> <goals> <goal>prepare-agent</goal> </goals> </execution> <execution> <id>report</id> <phase>test</phase> <goals> <goal>report</goal> </goals> </execution> </executions> </plugin> <plugin> <groupId>com.spotify</groupId> <artifactId>dockerfile-maven-plugin</artifactId> <version>1.4.13</version> <configuration> <repository>${project.artifactId}</repository> <tag>${project.version}</tag> <buildArgs> <JAR_FILE>target/${project.build.finalName}.jar</JAR_FILE> </buildArgs> </configuration> </plugin> </plugins> </build> </project>
|
最佳实践
1. 依赖管理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-framework-bom</artifactId> <version>${spring.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <exclusions> <exclusion> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> </exclusion> </exclusions> </dependency>
|
2. 构建优化
1 2 3 4 5 6 7 8 9 10 11
| mvn clean install -T 4
mvn clean install -DskipTests
mvn clean install -o
mvn clean install -pl module1,module2 -am
|
3. 仓库配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| <settings> <mirrors> <mirror> <id>aliyun</id> <mirrorOf>central</mirrorOf> <url>https://maven.aliyun.com/repository/central</url> </mirror> </mirrors> <profiles> <profile> <id>jdk-11</id> <activation> <activeByDefault>true</activeByDefault> <jdk>11</jdk> </activation> <properties> <maven.compiler.source>11</maven.compiler.source> <maven.compiler.target>11</maven.compiler.target> </properties> </profile> </profiles> </settings>
|
Apache Maven作为Java生态系统的标准构建工具,其简化的项目管理和强大的依赖管理功能极大地提高了Java项目的开发效率。通过标准化的项目结构和生命周期,Maven使得Java项目的构建、测试和部署变得简单而一致。
版权所有,如有侵权请联系我