Maven 构建 Java 项目

创建 Java 项目

方法 1:使用 Maven Archetype

# 创建简单 Java 项目 $ mvn archetype:generate \ -DgroupId=com.example \ -DartifactId=my-java-app \ -DarchetypeArtifactId=maven-archetype-quickstart \ -DinteractiveMode=false # 创建 Web 项目 $ mvn archetype:generate \ -DgroupId=com.example \ -DartifactId=my-web-app \ -DarchetypeArtifactId=maven-archetype-webapp \ -DinteractiveMode=false

方法 2:手动创建项目结构

my-java-app/ ├── pom.xml └── src/ ├── main/ │ ├── java/ │ │ └── com/ │ │ └── example/ │ │ └── App.java │ └── resources/ │ └── application.properties └── test/ ├── java/ │ └── com/ │ └── example/ │ └── AppTest.java └── resources/

基本 POM 配置

<?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-java-app</artifactId>
    <version>1.0.0</version>
    <packaging>jar</packaging>
    
    <name>My Java Application</name>
    <description>A sample Java application built with Maven</description>
    
    <properties>
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <junit.version>5.9.2</junit.version>
    </properties>
    
    <dependencies>
        <!-- JUnit 5 测试框架 -->
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>
        
        <!-- 日志框架 -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>2.0.7</version>
        </dependency>
        
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.4.7</version>
        </dependency>
    </dependencies>
    
    <build>
        <plugins>
            <!-- 编译插件 -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.11.0</version>
                <configuration>
                    <source>11</source>
                    <target>11</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
            
            <!-- 测试插件 -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>3.0.0</version>
            </plugin>
            
            <!-- JAR 插件 -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <version>3.3.0</version>
                <configuration>
                    <archive>
                        <manifest>
                            <mainClass>com.example.App</mainClass>
                        </manifest>
                    </archive>
                </configuration>
            </plugin>
        </plugins>
    </build>
    
</project>

示例代码

主类 (App.java)

package com.example;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class App {
    private static final Logger logger = LoggerFactory.getLogger(App.class);
    
    public static void main(String[] args) {
        logger.info("应用程序启动");
        
        App app = new App();
        String result = app.greet("Maven");
        
        System.out.println(result);
        logger.info("应用程序结束");
    }
    
    public String greet(String name) {
        return "Hello, " + name + "!";
    }
}

测试类 (AppTest.java)

package com.example;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.DisplayName;
import static org.junit.jupiter.api.Assertions.*;

class AppTest {
    
    @Test
    @DisplayName("测试问候方法")
    void testGreet() {
        App app = new App();
        String result = app.greet("World");
        assertEquals("Hello, World!", result);
    }
    
    @Test
    @DisplayName("测试空字符串")
    void testGreetWithEmptyString() {
        App app = new App();
        String result = app.greet("");
        assertEquals("Hello, !", result);
    }
}

构建和运行

编译项目

# 编译源代码 $ mvn compile # 编译测试代码 $ mvn test-compile

运行测试

# 运行所有测试 $ mvn test # 运行特定测试类 $ mvn test -Dtest=AppTest # 跳过测试 $ mvn compile -DskipTests

打包项目

# 创建 JAR 文件 $ mvn package # 清理并打包 $ mvn clean package # 运行 JAR 文件 $ java -jar target/my-java-app-1.0.0.jar

高级配置

创建可执行 JAR

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-shade-plugin</artifactId>
    <version>3.4.1</version>
    <executions>
        <execution>
            <phase>package</phase>
            <goals>
                <goal>shade</goal>
            </goals>
            <configuration>
                <transformers>
                    <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                        <mainClass>com.example.App</mainClass>
                    </transformer>
                </transformers>
            </configuration>
        </execution>
    </executions>
</plugin>

生成源码和文档 JAR

<!-- 源码 JAR -->
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-source-plugin</artifactId>
    <version>3.2.1</version>
    <executions>
        <execution>
            <id>attach-sources</id>
            <goals>
                <goal>jar</goal>
            </goals>
        </execution>
    </executions>
</plugin>

<!-- Javadoc JAR -->
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-javadoc-plugin</artifactId>
    <version>3.5.0</version>
    <executions>
        <execution>
            <id>attach-javadocs</id>
            <goals>
                <goal>jar</goal>
            </goals>
        </execution>
    </executions>
</plugin>

多模块项目

父项目 POM

<project>
    <modelVersion>4.0.0</modelVersion>
    
    <groupId>com.example</groupId>
    <artifactId>multi-module-app</artifactId>
    <version>1.0.0</version>
    <packaging>pom</packaging>
    
    <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>
    </properties>
    
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.junit.jupiter</groupId>
                <artifactId>junit-jupiter</artifactId>
                <version>5.9.2</version>
                <scope>test</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
</project>

子模块 POM

<project>
    <modelVersion>4.0.0</modelVersion>
    
    <parent>
        <groupId>com.example</groupId>
        <artifactId>multi-module-app</artifactId>
        <version>1.0.0</version>
    </parent>
    
    <artifactId>common</artifactId>
    
    <dependencies>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter</artifactId>
        </dependency>
    </dependencies>
</project>

常用构建命令

# 完整构建流程 $ mvn clean compile test package install # 快速构建(跳过测试) $ mvn clean package -DskipTests # 运行特定阶段 $ mvn clean $ mvn compile $ mvn test $ mvn package # 查看依赖树 $ mvn dependency:tree # 查看有效 POM $ mvn help:effective-pom # 运行应用程序 $ mvn exec:java -Dexec.mainClass="com.example.App"

IDE 集成

现代 IDE 都对 Maven 提供了良好的支持:

最佳实践