一、先搞清楚 Project Structure 里有什么
在该 IDE 中,Project Structure 是整个项目配置的核心。它不是一个简单的设置页面,而是由多个层级组成的配置体系。
打开 Project Structure 之后,你会看到左侧有几个大的分类:Project、Modules、Libraries、Facets、Artifacts。每个分类下面都有各自的职责,搞清楚它们各自管什么,是配置正确的前提。
- Project:这是最顶层的配置,主要管整个项目的 SDK、语言版本、编译器输出路径等全局设置。
- Modules:这是项目的核心单元。一个项目可以包含多个 Module,每个 Module 相当于一个独立的编译单元,有自己的源码目录、测试目录、依赖关系。
- Libraries:用来管理项目中使用的各种 JAR 包和类库。没有 Maven 的项目,所有第三方依赖都要在这里手动添加。
- Facets:这是对 Module 的进一步细化,比如 Web 项目需要配置 Web Facet,Spring 项目需要配置 Spring Facet。它决定了 IDE 如何理解和处理这个 Module。
- Artifacts:用来配置最终的输出产物,比如 WAR 包、JAR 包等。这是项目部署时真正需要的东西。
理解了这五个部分的分工,接下来的配置就有了清晰的思路。
二、Project 层面的配置:打好地基
Project 层面的配置是最基础的,也是最容易被忽略的。
首先是 SDK 的选择。点击 Project SDK,选择你机器上安装的 JDK 版本。这里有个常见的坑:很多人的电脑上装了多个 JDK 版本,但项目需要的是特定版本。如果选错了,编译出来的字节码版本和运行时不一致,就会报各种奇怪的错误。
然后是 Project language level。这个选项决定了编译器允许使用的语法特性。比如你选了 JDK 8,但 language level 选了 11,那你在代码里用了 JDK 11 才有的语法,编译时就会出问题。一般建议和 SDK 版本保持一致。
Project compiler output 是编译输出路径。默认情况下,该 IDE 会把编译后的 class 文件放到项目根目录下的 out 文件夹里。如果你的项目有特殊要求,比如需要输出到某个特定目录,可以在这里修改。但对于大多数项目,保持默认就可以了。
还有一个容易被忽略的选项:Project compiler output path for modules。如果你的项目有多个 Module,这里可以为每个 Module 单独指定输出路径。一般不需要动,除非你有特殊的目录结构需求。
三、Modules 配置:项目的骨架
Modules 是整个配置中最重要的部分。没有构建工具的项目,Module 的配置直接决定了项目能不能正常工作。
点击左侧的 Modules,你会看到当前项目的所有 Module 列表。如果项目只有一个 Module,通常就是项目名本身;如果有多个,每个都需要单独检查。
选中一个 Module,右侧会显示几个关键的 Tab:
Sources Tab:这里配置源码目录。该 IDE 需要知道哪些目录是源码根目录,哪些是测试源码目录。通常 src/main/java 是主代码目录,src/test/java 是测试代码目录。如果你的项目目录结构不是这种约定,需要手动在这里添加。
关键点:只有被标记为 Sources Root 的目录,里面的代码才会被编译。如果你的代码在某个目录下但没有被标记,IDE 会认为那只是普通文件,不会编译它。这是新手最常遇到的问题之一。
Paths Tab:这里配置编译输出路径和模块依赖。Output path 就是这个 Module 编译后的 class 文件放在哪里。
Dependencies Tab:这是没有 Maven 的项目中最关键的配置之一。点击加号,你可以添加几种类型的依赖:
- JARs or directories:添加本地的 JAR 包或者目录。这是手动管理依赖的主要方式。
- Library:添加一个该 IDE 内部的 Library,后面会详细讲。
- Module:添加对其他 Module 的依赖。如果你的项目拆分成了多个 Module,它们之间的依赖关系就在这里配置。
这里有个重要原则:依赖要按顺序添加,被依赖的 Module 要先编译。如果 A 依赖 B,那 B 必须在 A 之前配置好。
四、Libraries 配置:管理你的依赖
没有 Maven 自动拉取依赖,所有的第三方 JAR 包都需要手动添加到 Libraries 中。
点击左侧的 Libraries,然后点击加号,选择 Java。接下来你需要指定 JAR 包的路径。你可以一个一个添加,也可以一次性选中整个 lib 目录下的所有 JAR 包。
添加完成后,回到 Module 的 Dependencies Tab,把刚才创建的 Library 添加进去。这样,这个 Module 就能使用这些 JAR 包中的类了。
有几个实用技巧:
第一,建议把所有第三方 JAR 包统一放在一个 lib 目录下,这样管理起来方便,也便于版本控制。
第二,如果某个 JAR 包有对应的源码包或者文档包,可以在 Library 配置中一并添加。这样在开发时可以直接查看源码,提升效率。
第三,如果同一个 JAR 包被多个 Module 使用,不需要重复添加。在 Libraries 中添加一次,然后在每个需要的 Module 的 Dependencies 中引用同一个 Library 即可。
五、Facets 配置:让 IDE 理解你的项目
Facets 是很多人会跳过的部分,但对于某些类型的项目来说,它是必不可少的。
比如你的项目是一个 Web 应用,那就需要配置 Web Facet。配置之后,IDE 才知道你的 web.xml 在哪里,Web 资源目录在哪里,编译后的文件应该放到哪个目录下。
再比如 Spring 项目,配置 Spring Facet 之后,IDE 才能识别 Spring 的配置文件,提供依赖注入的导航和提示。
配置 Facet 的方式很简单:选中 Module,点击加号,选择对应的 Facet 类型,然后按照向导一步步配置即可。
如果你不确定自己的项目需要什么 Facet,可以先不配置,等遇到具体问题时再回来添加。
六、Artifacts 配置:定义最终输出
Artifacts 配置的是项目最终要生成什么东西。对于没有构建工具的项目,这一步尤其重要,因为没有 Maven 帮你打包,你需要手动告诉 IDE 怎么生成可部署的产物。
点击左侧的 Artifacts,点击加号,选择你要生成的类型,比如 JAR、WAR 或者 Exploded。
配置过程中,你需要指定:
- 输出目录:最终文件放在哪里
- 包含哪些内容:编译后的 class 文件、配置文件、依赖的 JAR 包等
对于 Web 项目,通常选择 Exploded 格式,这样生成的是一个目录结构,可以直接部署到应用服务器上。
配置完成后,还需要在 Module 的 Dependencies 中把这个 Artifact 添加进去,这样每次编译时就会自动生成。
七、常见问题排查
配置完成后,如果还是有问题,可以按以下思路排查:
问题一:类找不到,提示无法解析符号
大多数情况是依赖没有添加到 Module 中。检查 Module 的 Dependencies Tab,确认所有需要的 JAR 包都已经添加。
问题二:编译通过但运行时报 ClassNotFoundException
这通常是运行时缺少依赖。检查 Artifacts 配置,确认依赖的 JAR 包是否被包含在最终输出中。
问题三:模块之间互相依赖导致循环引用
这是架构问题,需要重新梳理模块依赖关系。原则上,模块之间的依赖应该是单向的,不能形成环。
问题四:语言版本不匹配
检查 Project 和 Module 两个层面的 language level 是否一致,是否和你使用的 JDK 版本匹配。
八、一些最佳实践
最后分享几个在实际工作中总结出来的经验:
第一,即使不用 Maven,也建议保持统一的目录结构。至少做到源码目录和测试目录分离,第三方依赖统一放在 lib 目录下。
第二,善用该 IDE 的 scope 功能。在添加依赖时,可以指定 Compile、Runtime、Test 等不同的 scope,这样可以防止不必要的依赖传递,也能让项目结构更清晰。
第三,定期检查 Project Structure。项目迭代过程中,难免会有人随意添加依赖或者修改配置,定期回顾可以防止配置逐渐混乱。
第四,把 Project Structure 的配置纳入版本控制。虽然该 IDE 的配置文件可以被版本控制,但对于没有构建工具的项目,这些配置就是项目能正常运行的保障,丢了就很麻烦。
写在最后
没有 Maven 的项目确实需要更多的手动配置工作,但这并不意味着它就低人一等。很多长期运行的内部系统、一些老旧的遗留项目,都是这种形态。掌握 Project Structure 的配置方法,是每个开发工程师的基本功。
希望这篇文章能帮你在面对这类项目时,少走一些弯路。配置这件事,一旦弄明白了,其实并不复杂,关键是要知道每个选项在干什么,以及为什么要这样配。