聊到用Maven创建项目,不少朋友第一反应是:IDEA里点几下就建好了,有什么好讲的?这话对,也不对。点几下确实能拉出一个能跑的小项目,但你真的搞清楚Maven在你电脑上做了什么、配置文件在哪、依赖从哪来吗?一旦碰到依赖下载失败、本地仓库路径不对、Web项目打不了war包这些破事,没有Maven这层基本功撑底,排查起来真的会让你怀疑人生。
这篇内容不打算写成翻来覆去的官方文档式教程,而是把你用Maven创建项目过程中会遇到的真实场景都过一遍:从Maven到底是干嘛的,到下载安装、环境变量、阿里云仓库配置,再到命令行创建项目和IDEA 2024创建Web项目,最后是依赖管理和高频报错排查。基本都是我这些年一线干活时的流程和习惯,希望帮你少走几步弯路。
1. 先搞清楚Maven在项目里到底扮演什么角色
太多人把Maven当成“一个下载依赖的工具”,这理解不算错,但格局小了。Maven本质上是一套项目构建和依赖管理的标准化框架,它把“项目长什么样、怎么编译、怎么打包、怎么依赖第三方库”这些事,用一套约定俗成的规则固化下来。你按它的规矩建项目,它就能帮你自动化搞定后续一系列繁琐操作。
这么说吧,没有Maven的时候,一个Java Web项目的依赖管理是这样的:你自己去官网下载jar包,手动扔进WEB-INF/lib目录,写完代码再用Ant脚本或者干脆用IDE的导出功能打成war包。jar包版本冲突了?自己排查。同事电脑上编译不过?多半是本地缺了某个包。这些问题在小型项目里忍忍就过去了,一旦项目变大,依赖变多,这套全靠人肉的方式基本是灾难。
Maven的解决方案是引入坐标和仓库两个概念。坐标就是每个构件(jar包)的唯一标识,由groupId、artifactId、version组成,就像快递的收货地址一样,全世界唯一。仓库则是jar包的集中存储地,分为本地仓库和远程仓库。你在pom.xml里声明依赖坐标,Maven就根据坐标去本地仓库找,找不到就去远程仓库(比如Maven中央仓库,或者你配置的阿里云镜像)下载,下载完存到本地仓库,下次直接用。这个过程就是依赖管理。
也就是说,Maven创建项目这个动作背后,其实是建立了一套“项目模板 + 依赖获取 + 构建流程”的标准机制。你创建的不只是一堆文件夹和XML文件,而是一个能被Maven统一管理的、可复制的、有清晰生命周期的工程结构。
这里有个关键认知要建立:Maven和IDE是两回事。IDEA只是替你调用了Maven的命令,真正干活的是Maven本身。所以不管你是用IDEA、Eclipse、VS Code还是纯命令行,只要机器上有Maven,项目的构建能力就都有保障。我见过不少同事在IDEA里配置错了Maven路径,结果整个项目组就他一个人编译不过,其实就是IDEA没找到正确的Maven,不是代码问题。
2. 创建项目之前,先把这三样配置落到实处
很多教程一上来就让你跑mvn archetype:generate建项目,结果新手跑一步错一步,最后发现是Maven压根没装好。所以我建议在个创建项目之前,先把Maven安装、环境变量、仓库镜像这三件事一次配置到位,后面所有操作都顺了。
2.1 下载安装:Maven和JDK的版本对应关系别搞错
Maven本身是Java写的,运行它必须要有JDK。但这里有个特别容易踩的坑:不同版本的Maven对JDK版本有最低要求,而项目编译用的JDK版本和Maven运行用的JDK版本是两码事。
先看一张我整理过的对应关系表,方便你下载时候对号入座:
| Maven版本 | 最低JDK版本 | 适合场景 |
|---|---|---|
| Maven 3.3.x | JDK 1.7 | 老项目维护 |
| Maven 3.5.x | JDK 1.7 | 老项目维护 |
| Maven 3.6.x | JDK 1.8 | 大多数公司项目 |
| Maven 3.8.x | JDK 1.8 | 大多数公司项目 |
| Maven 3.9.x | JDK 1.8+ | 建议新项目选用 |
| Maven 4.x | JDK 8+(部分功能需17) | 尝鲜或新团队 |
我的经验是,新项目直接选Maven 3.9.x配JDK 8或JDK 11,稳定而且兼容性好。别盲目追新,Maven 4.x虽然出来了,但很多公司私服插件、老项目的兼容性验证还没跟上,真没必要给自己找事。
下载的话,直接去Apache官网,注意看准apache-maven-3.9.x-bin.zip这个文件,别下成源码包(-src.zip)。下载完解压到一个路径里,强烈建议路径不要带空格和中文,比如D:\dev\apache-maven-3.9.6,别丢到Program Files里,Windows下的权限问题和路径解析问题会让你怀疑人生。
2.2 环境变量:Windows、Mac、Linux各来一遍
装完Maven要配环境变量,目的是让命令行在任何目录下都能直接执行mvn命令。这里补一个原理:环境变量里的MAVEN_HOME是指向Maven解压目录的指针,PATH里加上%MAVEN_HOME%\bin,系统就知道上哪去找mvn这个可执行文件。
Windows下的操作很简单:右键“此电脑” → 属性 → 高级系统设置 → 环境变量。新建一个系统变量MAVEN_HOME,值为你的Maven解压目录,然后在Path变量里追加%MAVEN_HOME%\bin。做完之后开一个新的命令行窗口,输入mvn -v,能打印出版本信息就说明成了。
Mac和Linux用户更省事,改~/.bash_profile(或~/.zshrc)就行:
export MAVEN_HOME=/opt/apache-maven-3.9.6 export PATH=$PATH:$MAVEN_HOME/bin写完记得source ~/.bash_profile让它生效。
这里有一个经常被忽略的点:IDEA里配置的Maven不一定用的就是你命令行里的那个。IDEA默认会用自己内置的Maven,版本可能和你系统装的不一致。我建议在IDEA的Settings → Build Tools → Maven里,把Maven home path指到你系统安装的Maven目录,User settings file指到你下面要配的settings.xml,让命令行和IDE的行为完全统一。这个细节省掉了无数“明明命令行能编译,IDEA里却报错”的灵异事件。
2.3 本地仓库和阿里云镜像:这两个配置能救你命
Maven装好之后,默认的本地仓库路径在用户目录下的.m2/repository。我强烈建议把它改到一个专门的位置,比如Windows下改成D:\maven-repo,Mac下改成~/maven-repo。原因很实际:第一,系统盘空间有限,仓库越用越大,几百兆到几个G都很正常;第二,万一重装系统,把仓库目录单独放外面,分分钟就能恢复环境,不用重新下载几个G的jar包。
改路径要去Maven的conf/settings.xml里改:
<localRepository>D:/maven-repo</localRepository>接着是最关键的一步:配阿里云镜像仓库。默认的Maven中央仓库在国外,国内网络环境下下载依赖经常龟速甚至超时,配了阿里云镜像之后速度立竿见影。在settings.xml的<mirrors>节点里加上这个:
<mirror> <id>aliyunmaven</id> <mirrorOf>central</mirrorOf> <name>阿里云公共仓库</name> <url>https://maven.aliyun.com/repository/public</url> </mirror>这里解释一下mirrorOf的含义:central表示这个镜像只拦截中央仓库的请求。阿里云的public仓库其实聚合了中央仓库、jcenter和spring等常用仓库的内容,日常开发基本够用。
如果你们公司有自己的私服(比如Nexus或Artifactory),那镜像地址要换成私服地址,同时还要在settings.xml里加<servers>配置用户名密码。这里不再展开,但你要知道:镜像配置只在下载依赖时生效,不影响你本地工程的任何构建逻辑。
2.4 多个本地仓库和多个镜像仓库怎么处理
这个热搜问题我太有感触了。很多人电脑里有不止一个.m2目录,比如一个是以前Eclipse时代用的,一个是后来IDEA建的,里面都有不少jar包,想合并起来省得重新下载。
先说本地仓库多个的问题。不建议直接合并。仓库目录里每个jar包都有对应的_remote.repositories和_lastUpdated文件,这些记录了这个jar是从哪个仓库下载的、下载时间等元信息。你要强行把两个目录的文件拷贝到一起,大概率会碰到jar包损坏、依赖状态不完整的问题。正确的做法是:选定一个新的空目录作为统一仓库,然后把原来两个仓库里的jar和pom文件按照坐标路径复制过去。更省心的方法是直接改settings.xml指向那个jar包更多的仓库,另一个废弃,缺的让它重新下一遍,反而更干净。
至于多个镜像仓库,settings.xml里的<mirrors>节点可以配置多个镜像,但Maven只会为同一个仓库选择第一个匹配的镜像。如果你想实现“中央仓库用阿里云、spring仓库用spring官方镜像”这种分流效果,要把不同仓库的请求转发到不同镜像,需要依赖仓库本身的<id>来区分,比如:
<mirror> <id>aliyun</id> <mirrorOf>central</mirrorOf> <url>https://maven.aliyun.com/repository/public</url> </mirror> <mirror> <id>spring-mirror</id> <mirrorOf>spring-milestones,spring-snapshots</mirrorOf> <url>https://maven.aliyun.com/repository/spring</url> </mirror>注意mirrorOf用的是仓库id的列表。这里有个细节:如果镜像配置了*(匹配所有仓库),那你新加的任何仓库都会走这个镜像,可能会把一些本来该从私服拉的依赖也指向错误地方,所以镜像是宁缺毋滥,能用中央仓库加阿里云兜底就够了。
3. 命令行创建Maven项目:摆脱IDE的第一步实操
配置完环境之后,最正统的Maven创建项目方式其实是命令行。很多人没试过,因为它看起来不如IDE图形界面直观。但命令行方式有两个不可替代的好处:第一,它可以在任何机器上复现同构的项目结构,适合CI/CD流水线;第二,它让你真正看到项目骨架的生成过程,对理解Maven的原理很有帮助。
3.1 用archetype:generate生成标准骨架
Maven创建项目最经典的方式是使用archetype(原型),你可以把它理解成一个项目的模板。在命令行输入:
mvn archetype:generate -DgroupId=com.example -DartifactId=demo-project -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false拆解一下这几个参数:
-DgroupId:组织标识,通常写公司域名倒序,比如com.yourcompany。它决定了项目里package的根路径,也决定了最终jar包坐标里的groupId。-DartifactId:项目名/模块名,对应jar包的artifactId。一般用小写中划线命名,比如demo-project。-DarchetypeArtifactId:模板类型。maven-archetype-quickstart是普通Java项目模板,maven-archetype-webapp是Web项目模板。-DinteractiveMode=false:跳过交互式问答,直接使用参数生成。
跑完这条命令,当前目录下会出现一个demo-project文件夹,里面有pom.xml、src/main/java、src/test/java等结构。
这里说一句经验:如果archetype:generate时卡住了,大概率是Maven正在从远程仓库下载archetype插件本身,第一次会比较慢。此时可以配好阿里云镜像再跑,别急着用Ctrl+C中断,多等一会儿。
3.2 项目目录结构背后的约定
创建完项目后,你看到的是这样的结构:
demo-project ├── pom.xml └── src ├── main │ ├── java │ │ └── com/example/App.java │ └── resources └── test └── java └── com/example/AppTest.java这套结构是Maven的约定优于配置思想的体现,也就是官方推荐的“标准布局”。你不需要在配置文件里告诉Maven源码在哪、测试代码在哪、打包输出到哪,只要按照这个惯例放置文件,Maven会自动识别。具体来说:
src/main/java:项目主源码src/main/resources:项目资源文件(配置文件、静态资源等),编译后会输出到classes目录src/test/java:单元测试代码target:Maven构建产物输出目录,编译后的.class文件、打好的jar包都在这
如果你创建的是Web项目(maven-archetype-webapp),还会多出src/main/webapp目录,用来存放WEB-INF/web.xml、JSP页面和静态资源。构建时Maven会把webapp的内容连同classes一起打进war包。
3.3 第一个pom.xml到底该怎么改
自动生成的pom.xml只是最基础的样子,需要手动补全关键信息。下面是一个日常开发中很典型的pom.xml骨架:
<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>demo-project</artifactId> <version>1.0-SNAPSHOT</version> <packaging>jar</packaging> <properties> <maven.compiler.source>8</maven.compiler.source> <maven.compiler.target>8</maven.compiler.target> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.13.2</version> <scope>test</scope> </dependency> </dependencies> </project>这里面有几个经常配置错的点:
第一,packaging决定了打包方式,jar是普通Java库,war是Web应用。新建项目时想清楚你要什么,Web项目必须改成war,否则打包出来没有WEB-INF结构,部署到Tomcat会直接404。
第二,properties里设置编译版本特别重要。很多人的报错源头就是这里,因为IDEA里项目语言级别和Maven编译器版本不一致,导致编译时出现“源选项8已不再受支持”或者“无效的目标发行版”之类的错误。在pom.xml里统一用maven.compiler.source和maven.compiler.target指定,比在IDE里肉眼排查靠谱得多。
第三,<version>用1.0-SNAPSHOT这种以-SNAPSHOT结尾的版本号是Maven的约定,表示这是一个开发中的快照版本。快照版本有个特点:Maven每次构建都会去远程仓库检查是否有更新。如果做的是正式发布,就该用不带SNAPSHOT的版本号,比如1.0.0。
4. 在IDEA 2024里创建Maven项目:普通人最常用的姿势
命令行会用以后,回到日常开发,绝大多数人还是用IDEA干活。IDEA 2024版本创建Maven项目的方法和老版本略有差异,但核心逻辑没变:告诉IDEA用哪个Maven,让Maven来建项目。
4.1 IDEA里全局Maven配置,一次配好到处用
打开IDEA,进入File → Settings → Build, Execution, Deployment → Build Tools → Maven,你会看到三个关键配置项:
Maven home path:Maven的安装目录User settings file:settings.xml的路径Local repository:本地仓库路径
如果你在命令行环节已经配置好了,这里直接把Maven home path指到本机Maven目录,IDEA会自动读取你的settings.xml并显示本地仓库地址。这里有一个IDEA 2024新增的特性需要注意:新版IDEA有时会提示你“是否使用内置的JBR(JetBrains Runtime)作为Maven的JRE”,一般不用管,保持默认即可。但如果你项目要求JDK 8,而IDEA内置JBR是17或21,Maven运行时会以JRE为准,可能出现编译版本不匹配,这时候手动把Runner → JRE指到项目的JDK就行。
我个人习惯是在Settings → Maven → Importing里勾选Import Maven projects automatically,这样pom.xml有任何改动,IDEA会自动刷新依赖,省得每次手动点刷新按钮。
4.2 创建普通Java项目:三步搞定
在IDEA 2024中创建普通Maven项目的流程是:
- 点
File → New → Project,左侧选择Maven(有些版本叫“生成器”里的Maven)。 - 右侧
Project SDK选好本地的JDK版本。 - 填好
GroupId和ArtifactId,点Create。
这里有个小变化:IDEA 2024版本的新建项目向导比老版本简洁不少,很多选项被收进了Advanced Settings里。如果你没看到GroupId和ArtifactId,点右下角的Advanced Settings展开就能找到。比如GroupId填com.example,ArtifactId填demo-project,生成之后IDEA会自动创建对应的包路径和pom.xml。
创建完成后,IDEA右下角会有一个Maven导入项目的进度提示。等它跑完,右侧的Maven工具窗口里就能看到项目的生命周期、依赖列表等。
如果你看到的项目结构里src目录是折叠的,或者没有src/main/java目录,不用慌。在IDEA里选中src/main文件夹,右键New → Directory,输入java回车,IDEA会自动识别为源码目录。这个操作本质上是给Maven标准目录标上“源码根目录”的记号,因为IDEA有时候不会自动识别手动创建的目录角色。
4.3 创建Web项目:打包方式要先想清楚
创建Web项目和普通Java项目在步骤上几乎一样,区别在于pom.xml的packaging要改成war,并且要补齐src/main/webapp目录和web.xml。
具体操作:
新建Maven项目时,
Advanced Settings里可以选择Packaging为war,IDEA会自动生成Web项目骨架。如果创建的是普通jar项目,想转成Web项目,在pom.xml里把
<packaging>jar</packaging>改成<packaging>war</packaging>,然后在src/main下新建webapp目录,再右键webapp→New → File,创建WEB-INF/web.xml。在pom.xml里加上Servlet和Tomcat相关依赖,比如:
<dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>4.0.1</version> <scope>provided</scope> </dependency>注意provided这个scope很关键,它表示这个jar由运行环境(Tomcat)提供,打包的时候不会被打进war包。如果不加provided,打完的war包里会多出一份servlet-api.jar,部署到Tomcat时很可能因为类重复加载导致冲突。
- 配置
maven-war-plugin指定war包名称,避免默认带版本号:
<build> <finalName>demo-web</finalName> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-war-plugin</artifactId> <version>3.4.0</version> </plugin> </plugins> </build>最后用IDEA右侧Maven工具窗口里的package命令打包,或者命令行mvn clean package,观察target目录下生成的demo-web.war。这个war包可以直接扔到Tomcat的webapps目录下运行。
5. 依赖管理实战:坐标、scope、传递依赖和clean install
创建完项目不等于结束,真正天天打交道的是依赖管理。我不会在这里堆概念,只讲几个实用到不能再实用的点。
5.1 坐标体系:一个依赖是怎么被找到的
在pom.xml里声明依赖,其实就是写一组坐标:
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.3.31</version> </dependency>这组坐标对应本地仓库里的路径:org/springframework/spring-context/5.3.31/spring-context-5.3.31.jar。你可以去本地仓库看一眼,路径结构和坐标是一一对应的,理解了这一点,以后遇到“找不到依赖”的问题时,你会下意识地打开本地仓库检查jar包到底在不在那个位置。
5.2 scope:同一个依赖,不同生命周期表现完全不同
<scope>是依赖管理里最容易翻车的概念,它的作用是控制依赖在编译、测试、运行、打包各个阶段的可见性。常见的几个:
| scope | 编译 | 测试 | 运行 | 打包进产物 | 典型场景 |
|---|---|---|---|---|---|
| compile(默认) | 是 | 是 | 是 | 是 | 项目运行时真正要用的库 |
| provided | 是 | 是 | 否 | 否 | Servlet API、Lombok(部分情况) |
| runtime | 否 | 是 | 是 | 是 | JDBC驱动,编译时不需要但运行时要 |
| test | 否 | 是 | 否 | 否 | JUnit、Mockito |
拿Servlet API举例最形象:你的代码在编译时要import javax.servlet.http.HttpServlet,所以编译期必须能看到这个类;但真正运行的时候,Tomcat自己带了一套Servlet实现,你的war包里如果再带一份,反而可能冲突。这时候provided就是最合适的。
5.3 传递依赖:项目里的“隐性依赖”是怎么来的
Maven依赖有一个传递特性:你只声明了spring-context,但它内部依赖的spring-core、spring-beans会被自动带进来。这是好事,省得你一个个手动补。但麻烦也在传递依赖上——如果两个库都传递依赖了同一个jar的不同版本,Maven会有自己的版本仲裁规则:声明顺序靠前的优先、路径近的优先。
解决冲突的办法是排除依赖:
<dependency> <groupId>com.example</groupId> <artifactId>some-lib</artifactId> <version>1.0.0</version> <exclusions> <exclusion> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> </exclusion> </exclusions> </dependency>另外,在IDEA的Maven工具窗口里点Show Dependencies,可以可视化查看依赖树,比对着XML硬猜效率高得多。我排查依赖冲突的常规操作就是先看依赖树,找到同一个groupId+artifactId出现多个版本的地方,再决定是排除还是统一版本。
5.4 clean install到底是干嘛的,为什么天天有人喊
clean install是Maven生命周期命令的组合,拆开看:
clean:清空target目录,把上一次构建的产物全部删掉。install:执行完整的构建生命周期,包括编译、测试、打包,然后把构建产物安装到本地仓库,供其他项目依赖。
之所以经常组合使用,是因为增量构建有时候会残留旧的class或陈旧资源,尤其当你改过配置文件、换了依赖版本、或者从别人仓库拉过代码之后,不clean一下,编译出来的东西很可能还是旧的。但clean install也有代价:它会清掉整个target,重新编译全部代码,大型项目耗时比较长。
实际工作中我的策略是:
- 提交代码前跑一次
mvn clean install确认本地能完整通过。 - 日常调试改代码,用
mvn compile或mvn package就够了,没必要每次clean。 - 如果只是改了
resources目录下的配置,甚至可以直接用IDEA的Build → Recompile重新编译,速度更快。
6. 常见问题与排查技巧实录
最后这部分,把我这几年遇到的Maven创建项目和日常使用的问题做个整理,都是真实的坑,遇到直接照着排查就行。
6.1 依赖下载失败:Could not resolve dependencies优先查三处
这个报错是出现频率最高的。排查顺序我是这么来的:
看网络。命令行ping一下仓库地址,或者直接浏览器访问
https://maven.aliyun.com/repository/public/,如果能打开,说明网络没问题,问题在Maven配置。看本地仓库有没有下载失败的残留。打开本地仓库,找到对应的jar包目录,如果里面有
.lastUpdated后缀的文件,说明上次下载中断了。处理办法是先把这个jar包对应的目录整个删掉(或者删掉所有.lastUpdated文件),再重新执行构建。因为Maven默认24小时才重新检查更新,你不删的话,重跑多少次都报一样的错。看settings.xml是否生效。在命令行执行
mvn help:effective-settings,查看当前生效的配置文件到底加载了哪些镜像和仓库。如果发现镜像没生效,检查settings.xml是不是放在了IDEA指定的路径下,而不是系统默认路径。
6.2 Maven与JDK版本不匹配:编译报错的元凶
最常见的报错是invalid target release: 11或Source option 11 is no longer supported。这两个都是编译器版本低于你指定版本导致的。检查思路:
- 环境变量里
JAVA_HOME指向的JDK版本是多少? - 项目pom.xml里
maven.compiler.source/target是多少? - 两者必须一致,或者编译版本低于JDK版本。
所以我会先用java -version确认当前默认JDK,再执行mvn -v,它会明确打印出Maven用的Java版本。两条命令一对比,就清楚Maven到底跑在哪个JDK上了。
6.3 两个本地仓库合并:别复制完就完事
前面提过合并仓库的问题,这里给一个最省事但安全的做法:与其合并,不如统一。把你的settings.xml指向现在jar包更全的那一个仓库,然后定期让Maven自动补齐缺失依赖。因为一个活跃项目的依赖基本都会被再次下载,那些“缺”的jar,随着你编译、测试、打包,很快就会被重新拉回来。除非你离线开发,否则没必要花时间手动合并一堆_repositories元数据可能不一致的文件。
6.4 IDEA提示找不到Maven或依赖全部标红
出现这个情况,先不要怀疑代码。按顺序检查:
File → Settings → Maven,确认Maven home path是本机安装的Maven,不是IDEA内置的。- 确认
User settings file指向了配置过阿里云镜像的settings.xml。 - 打开
pom.xml,看dependencies标签下有没有被IDEA标黄或标红。然后触发一次Reload All Maven Projects(Maven工具窗口左上角的刷新按钮)。 - 如果还是红的,去本地仓库看jar包下没下来。如果
.lastUpdated文件一堆,删除后重新reload。
另外还有一个小细节:IDEA的代理设置。如果你公司网络需要走代理访问外网,但IDEA的代理没有配置,也会导致依赖下载失败。在Settings → Appearance & Behavior → System Settings → HTTP Proxy里,选择“Auto-detect”或者手动指定公司代理即可。这个问题经常被忽略,和Maven本身无关,但表现却是Maven依赖下载失败。
6.5 Web项目创建后没有src/main/webapp,或者打不出war包
不少朋友用IDEA 2024创建Maven项目时,选了Web框架支持,结果项目里没有webapp目录。原因通常是:IDEA的Web框架支持只是改变了项目facets,但没有创建webapp目录。解决方式有两条:
- 手动新建
src/main/webapp目录,然后右键webapp→Add Framework Support → Web,让IDEA把它识别为Web资源目录。 - 如果pom.xml里
packaging是war,但打完的包总是jar,那就是打包配置被IDEA项目设置里的Packaging覆盖了。检查Project Structure → Artifacts里是否有旧的jar类型配置,删掉重建war类型的artifact就好。
这里补一个打包相关的心得:打完包后,一定要用压缩工具或者命令行看一眼war包内容,确认WEB-INF/classes里有你的class文件和resources,WEB-INF/lib里有你运行时的依赖。养成这个习惯,基本不会出现“本地运行正常,部署到服务器就404”的尴尬。
7. 命令行构建和IDEA构建怎么配合,聊聊我自己的习惯
这个点虽然不算创建项目的必需流程,但属于日常操作里很能提升效率的技巧。我见过不少同事永远在IDEA里点那一个小锤子按钮,从没在命令行跑过mvn,以至于部署到Linux服务器上时,连怎么编译打包都抓瞎。
我的建议是:平时开发用IDEA的图形界面操作,方便快捷;但每周至少用命令行完整跑一次mvn clean install -DskipTests,保证项目在纯净环境下能构建通过。因为IDEA的构建和Maven命令行的构建在某些细节上并不完全一致,IDEA对源码做了很多自动化的增量处理,可能掩盖了pom.xml配置缺失的问题。而CI/CD流水线上跑的是纯Maven命令,你在本地命令行能过,才是真正的“能过”。
另一个很实用的点是跳过测试。-DskipTests是跳过测试编译和运行,-Dmaven.test.skip=true是跳过测试代码的编译。我自己在打发布包时常用-DskipTests,因为测试代码已经编译过了,跳过运行就行;但如果是拉下来的新代码,第一次构建,建议不要跳过测试,先跑一遍确认测试用例都过。
命令行多熟练一点,对后面接触多模块项目、搭CI流水线、排查线上构建问题,都是直接加分的能力。Maven说白了不是个多高深的东西,它就是一套规范加一组建构工具,把这套规范吃透,创建项目这件事才算真正入门。
最后再说一个我的个人体会:Maven创建项目最核心的价值不是“建项目”这个动作本身,而是让你养成一切配置都有出处、所有操作都可复现的习惯。pom.xml写明白,settings.xml配清楚,目录结构守标准,后面无论换工具、换机器还是换同事,这套工程都不会散架。那些在一个项目里折腾得灰头土脸的日子,回头看,多数问题顽固不化的原因不是代码难写,而是基础工程结构没扎稳。把这个地基打牢,比多学几个框架都值。