第一次接触Maven时,我被项目里那个叫pom.xml的文件搞懵了——为什么一个构建工具需要写这么多配置?直到接手一个老项目,看到lib目录下密密麻麻的200多个jar包互相冲突,才明白Maven存在的意义。现在连Android开发都转向了Maven依赖管理,这工具早已成为Java生态的基础设施。
本文将用我处理过的一个电商项目为例,带你从零配置IntelliJ IDEA环境开始,到用三种不同方式打包Spring Boot应用上线的完整过程。不同于官方文档的抽象说明,我会重点演示实际开发中:
在官网下载Maven时,新手常会直接选择最新版(如写作时的3.9.5),但这可能带来隐患。去年我们团队就因升级到3.8.1导致内部Nexus仓库鉴权失败,回退到3.6.3才解决。建议:
安装后执行mvn -v验证,应该看到类似输出:
bash复制Apache Maven 3.6.3
Maven home: /usr/local/Cellar/maven/3.6.3/libexec
Java version: 1.8.0_301
在File > Settings > Build Tools > Maven中:
-Xmx512m(默认256m在大型项目会OOM)重要:不要使用IDEA内置的Maven!不同版本IDEA捆绑的Maven版本可能引发奇怪问题,始终使用手动安装的版本。
这是新手最易踩坑的部分。假设我们要开发一个电商系统,pom.xml中常见依赖如下:
xml复制<dependencies>
<!-- Spring Boot Starter -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.7.0</version>
</dependency>
<!-- 数据库 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<!-- 测试 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
避坑指南:
xml复制<properties>
<spring-boot.version>2.7.0</spring-boot.version>
</properties>
ClassNotFoundException时,用mvn dependency:tree查看依赖树xml复制<exclusions>
<exclusion>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</exclusion>
</exclusions>
在resources目录下建立:
然后在pom.xml中配置profiles:
xml复制<profiles>
<profile>
<id>dev</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<env>dev</env>
</properties>
</profile>
<profile>
<id>prod</id>
<properties>
<env>prod</env>
</properties>
</profile>
</profiles>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>application-${env}.properties</include>
</includes>
</resource>
</resources>
</build>
启动时通过-P参数指定环境:mvn spring-boot:run -Pprod
xml复制<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
执行mvn package生成的可执行jar包含嵌入式Tomcat,直接通过java -jar运行。
常见问题:
<resources>-Djarmode=layertools优化层打包xml复制<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
需要重写SpringBootServletInitializer:
java复制public class ServletInitializer extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(Application.class);
}
}
创建src/assembly/dist.xml:
xml复制<assembly>
<id>dist</id>
<formats>
<format>zip</format>
</formats>
<fileSets>
<fileSet>
<directory>target</directory>
<includes>
<include>*.jar</include>
</includes>
<outputDirectory>/lib</outputDirectory>
</fileSet>
<fileSet>
<directory>src/main/scripts</directory>
<outputDirectory>/bin</outputDirectory>
<fileMode>0755</fileMode>
</fileSet>
</fileSets>
</assembly>
pom.xml配置:
xml复制<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
<configuration>
<descriptors>
<descriptor>src/assembly/dist.xml</descriptor>
</descriptors>
</configuration>
</plugin>
| 问题现象 | 可能原因 | 解决方案 |
|---|---|---|
编译时报程序包不存在 |
依赖未下载成功 | 1. 检查网络 2. 删除本地仓库对应目录重新下载 |
| 不同环境配置不生效 | profile未激活 | 1. 检查-P参数2. 执行 mvn help:active-profiles |
| 打包后文件缺失 | 资源过滤配置错误 | 检查<resources>配置 |
| 依赖冲突 | 多个版本共存 | 使用mvn dependency:tree -Dverbose分析 |
终极调试技巧:
当遇到诡异问题时,按顺序执行:
mvn clean 清理历史构建mvn dependency:purge-local-repository 清除依赖缓存target目录最后分享一个真实案例:某次发版后应用无法启动,日志显示NoSuchMethodError,最终发现是某个间接依赖引入了老版本的Guava。通过<dependencyManagement>统一管理所有依赖版本才彻底解决。这也让我养成了在父POM中锁定所有依赖版本的习惯。