10

IDEA跟Eclipse险些打一架。Maven:都住手,我来一统天下

 3 years ago
source link: https://mp.weixin.qq.com/s?__biz=MzI0MTUwOTgyOQ%3D%3D&%3Bmid=2247493739&%3Bidx=1&%3Bsn=0c8d4c00ec41862d033c93662cab554e
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
famIner.png!mobile

前言

你好,我是A哥(YourBatman)。

做Java开发这么久了,是否曾经疑问过:

  1. 为何项目中的xxx.iml、.idea文件夹明明起到重要作用,却不能被提交到git仓库,否则工资容易受损呢?

  2. 这个项目他是用Eclipse开发的,我现在要用IDEA继续,担心结构上出现问题?

  3. 为什么一个Maven项目被导入进IDEA了能正常work,它的项目结构Project Structure是咋样的?

若你也有这些疑问,那么看到本文你就来对了。

IntelliJ IDEA和Eclipse作为当下最为流行的两大IDE,它们在界面、操作、项目管理上是有很大差异的。正所谓 两派之争必有一斗 ,到底该以谁的项目结构为标准?谁又选择去妥协呢?No,二者的答案都是这个

bmYRNnv.png!mobile

本文提纲

7zmUvaF.png!mobile

版本约定

  • IntelliJ IDEA:2020.3.2

  • SpringToolSuite:4.9.0.RELEASE

正文

接下来本文就从项目层面开始,探究这些问题都是如何被解决的~

IntelliJ IDEA项目

来吧,都在该系列的前俩篇文章里:

  1. 谁再把IDEA的Project比作Eclipse的Workspace,我就跟谁急

  2. 玩转IDEA项目结构Project Structure,打Jar包、模块/依赖管理全搞定

Eclipse项目

因为Eclipse项目本系列文章并未提及过,所以这里简单的介绍下。

实话说,A哥自2015年入行就从没用过原生的eclipse,所以这里就以基于Eclipse的 STS 为例了哈,道理都一样。

ANfiqyz.png!mobile

Eclipse它有workspace操作空间的概念,所有Project项目都是放在操作空间里管理起来的。换句话讲,Eclipse的一个窗口打开的是一整个工作空间,里面有多少Project就加载进来多少个,因此它可以实现: 一个窗口同时打开多个Project项目

新建一个Project

以新建一个名为hello的java项目为例: File -> New -> Java Project...

FBJRvyY.png!mobile

习惯了IDEA的选手,看到这个eclipse的这个页面,是否想感叹一句:一个项目创建页面为毛整这么复杂?像JRE、working sets这种选项完全没必要在创建时让选嘛,页面太不精简了,干扰信息太多。

点击Next:

vE3Unm3.png!mobile

呃,同样的感觉,且不说是新手,即使是老手看到这个页面也“乱花渐欲迷人眼”吧,O(∩_∩)O哈哈~。eclipse的页面设计基本都有这个毛病:过于复杂,干扰选项太多。比如这里插一个class类的创建页面,你感受一下:

7v26bie.png!mobile

点击Finish,Project创建完成了。

imqYNn3.png!mobile

Project项目设置

鼠标选中项目(和IDEA不一样,此处必须 选中 ),右键选择Properties就可以对该项目进行配置:

QjIjqm3.png!mobile

配置项“多如牛毛”,令人望而生畏呀。这里就不一一介绍了,图形化的东西了解起来也容易。但是你是否发现,众多配置项中却不见Module字样,怎么肥四?

Eclipse没有Module概念

如果想在hello项目下创建一个hello-client项目怎么办?答曰:在 逻辑 层面eclipse做不到,只能在路径结构下体现,具体创建动作为:点击新建项目,然后自定义这个路径,把它放在hello下面。

RZfYZrz.png!mobile

点击Finish后,项目结构上看如下图所示:

I36v6fE.png!mobile

上图是 Project Explorer ,但若你切换到 Package Explorer 的话截图如下:

Q36FVff.png!mobile

从这里能看出,eclipse在逻辑上是 不存在层级概念 的,没有module只有Project。

即便你导入的是maven项目(maven有模块概念)也是这样子,这里以dubbo为例: I7v2Uj6.png!mobile

i2uAfqA.png!mobilePackage Explorer视图

所以请记住,这是和IDEA在逻辑结构上非常大的不同: Eclipse里并不存在Module,并不存在Module,并不存在Module。

解释.classpath和.project

eclipse的每个项目,还有两个附加文件: .classpath文件和.project文件 。这两个文件比较特殊,没有文件名,以.开头,是隐藏文件。

maimAvz.png!mobile

看过A哥上篇文章( 谁再把IDEA的Project比作Eclipse的Workspace,我就跟谁急 )的同学知道IDEA里有两个特殊的文件 workspace.xml${moduleName}.iml ,同样的eclipse里也有,我们可粗略的称作它们为环境描述符和项目描述符。

.classpath文件

.classpath文件存储了项目编译时 Java构建路径 ,这个路径用$CLASSPATH可引用到。hello项目的此文件内容如下:

BZBryqI.png!mobile

简而言之,.classpath定义了这个项目在编译时所使用的$CLASSPATH类路径。

.project文件

.project提供了项目的完整描述,包括名称、描述、项目类型等等。

RvayYby.png!mobile

对几个标签稍稍解释下:

  • name:项目名称,一般和文件夹名称同名,但它们是两码事

  • comment:项目注释

  • buildCommand:构建使用的命令。这里值是 org.eclipse.jdt.core.javabuilder ,也就是说是eclipse帮你编译的,而非你自己手动输入java命令编译
  • natures:项目类型,这里 org.eclipse.jdt.core.javanature 表示一个java项目

简而言之,.project是项目描述符,有了这个文件,eclipse加载项目时就可以按照它显示啦。

解释.settings目录

eclipse项目.settings目录下的配置比较杂,各种后缀名的都 可能 见到,绝大多数是文本文件,格式为properties或xml。Properties类型文件多数以.prefs为后缀名,XML类型文件多数以.*、.xml为后缀名。

iaqiiyb.png!mobile

因为类型众多,这里介绍几个较为常见的代表一下:

  • org.eclipse.core.resources.prefs :规定文件的编码。尽量不要让一个项目中出现多种编码哟
yEf2yub.png!mobile
  • org.eclipse.jdt.core.prefs :指定一些Java编译的特性,比如编译版本、警告级别等等
Vn2Ij2r.png!mobile

结构差异,IDEA跟Eclipse打一架?

了解了IDEA和Eclipse的项目结构后发现,它俩对项目的管理方式是完全不一样的:

  1. 不同的逻辑结构

  2. 不同的元数据文件

  3. 元数据文件的内容、格式都不一样

nimaMjF.png!mobile

就因为这些差异的存在,就出现了不兼容问题:IDEA项目Eclipse不认识,反过来同理。虽然IDEA做了导入Eclipse项目的功能,但兼容性并不完美,完全是为了“协助”Eclipse倒戈IDEA的“权宜之计”而已~

也许你会说这影响不大呀,毕竟一个团队内一般不会出现既使用IDEA,又使用Eclipse的情况。诚然,一般确实不会有此类情况发生,but, 视野放大点 再想想呢?比如,如果是个开源项目呢?它面向的是所有开发者一起协作,总不能限制人家的IDE吧。还是拿dubbo来举例:要把源码全部提交到github上去的话,应该用IDEA的元数据文件还是Eclipse的呢?对于项目本身来说,项目名称、结构、依赖管理等 都在 元数据文件里保存着哩~

很明显,用谁的都不合适,毕竟现在Java平台的IDE还三足鼎立呢(至少还有两足),“得罪”任何一方都是不行的。况且,对于程序本身来说,IDE并不属于它的一部分,所以即便IntelliJ IDEA已一统天下了也不应该依靠它的元数据文件去帮你管理依赖、管理项目。 花无百日红 ,明天谁知道呢~

这样子炒来炒去不会有结论的,那怎么办,难道非得“动手”?

36ruae2.png!mobile

面对这种情况,需要做的就是 标准化 ,让所有的IDE都支持识别 同一种 项目/目录结构,问题自然迎刃而解了。这个时候有“人”就扛起了大旗,承担了这种角色的,它就是 Maven (发音为[ˈmevən],而不是“马瘟”)。

rMnuUf.png!mobile

不管是何种IDE,都能识别和加载maven项目,解析其pom.xml文件生成为IDEA自己的元数据文件即可正常完成加载啦。因此,对于开发者来说,只需要 面向Maven管理项目 即可,再也无需关心具体IDE,这种差异性交由它帮你摆平。继续拿dubbo举例,在实操中它确实也是这么干的:只往github里提交了maven结构的源码和pom.xml元数据文件:

6ZZnyy2.png!mobile

从此即使你用Eclipse,我用IDEA,也能正常的相爱了。

值得注意的是:既然使用了maven的项目结构,那么提交到github时,一些IDE自己的元数据文件就不能再提交了喽。因此,一般都会在项目的 .gitignore 文件里添加上如下配置项:

# eclipse ignore
.settings/
.project
.classpath

# idea ignore
.idea/
*.ipr
*.iml
*.iws

创建/导入Maven项目

既然Maven项目已然成为标准,因此在实际情况中不管是新创建,还是接触到的99.99都是maven项目。IDEA和Eclipse都提供了对maven项目的“完美”支持。

IDEA和Maven项目

创建Maven项目:

JvYrmq6.png!mobile

左边类别中选择Maven就表示需要创建一个maven项目,点击Next(当然你也可以选择一个模版骨架,如果公司有统一骨架的话):

q6Zju2A.png!mobile

点击Finish,打开一个新的IDEA窗口,大功告成:

QJNfqeY.png!mobile

继续创建两个子模块(hello-client和hello-service),同样也用Maven项目:

IrYN73R.png!mobile

点击Finish,并在子模块里添加Spring Context依赖:

neUfInz.png!mobile

并让hello-service模块依赖hello-client模块:

UZ7Nrqr.png!mobile

所以现在即使在hello-service模块里也能正常使用spring-conext相关类喽:

umiauin.png!mobile

什么原因?这时上篇文章 的内容就起作用啦,查看项目的结构 Project Structure 一探究竟:

EFjUBzY.png!mobile

hello-client模块里的依赖:spring-context

IBjiIv3.png!mobile

hello-service模块里的依赖:

7JRfyuy.png!mobile

这里有spring-context的依赖,所以就能够正常使用。

发现没有,在创建此项目时,开发者只需要关心Maven方式创建,模块依赖的时候也只需更改Maven的元数据文件pom.xml即可,IDEA我会自动“解析”好放在项目结构 Project Structure 里并保存在它自己的元数据文件中(如xxx.iml文件等),从而确保了正常运行和管理。

打开/导入Maven项目:

VzYrYjf.png!mobile

打开窗口,选中pom文件(或者顶层文件夹)即可搞定。

导入maven模块时稍微有点不一样,了解一下:

注意:在IDEA里Project项目是不存在import导入这么一说的,因为它是个独立体,只能说是打开项目

nMnMNbV.png!mobile

选中某个文件夹后,确定进入下一步:

aEfeUjR.png!mobile

如图,IDEA支持把 多种类型 的模块导入进来,不可谓不强大:

  • Android Gradle:若是安卓项目,选此项

  • Eclipse:若是Eclipse项目,选此项(请注意:有eclipse元数据文件的才叫eclipse项目,而并不是对方用Eclipse开发就一定是eclipse项目,毕竟还有可能是maven项目嘛)

  • Gradle项目:若是Gradle项目,选此项。比如Spring Framework项目

  • maven项目:99%情况下,我们选择的应该都是此项

点击Finish即可把该模块导入进来了。

值得一提:很多“老程序员”在一个IDEA窗口里看似显示了多个“项目”,其实就是把一个Project当作一个Module模块导入进来了,这样做是 非常不建议 的,不信打开你的 Project Structure 瞅一眼,简直乱如麻,就是灾难无法管理。本系列前面文章详细介绍了这么做不妥的原因,并给了最佳实践,欢迎前往参阅。

Eclipse和Maven项目

大同小异,略。

Maven一统天下

说明:本文并非Maven专题,仅对其一统天下的现状简单聊几句

7FR3Q3M.png!mobile

Maven是一个 项目管理工具 :包含了一个项目对象模型 (POM:Project Object Model),一组 标准项目结构 ,一个项目生命周期(Project Lifecycle),一个依赖管理系统(Dependency Management System),和用来运行定义在生命周期阶段(phase)中插件(plugin)目标(goal)的逻辑。

Maven的每个功能都是杀手级别的存在,非常强大和好用,中大型项目必备。譬如其依赖管理系统,若没有它的话依赖一个Jar得先去官网down一个对应版本的下来,然后添加到IDE里,打包的时候一起打进去,可谓麻烦至极且容易出错。

也不知道Maven什么时候早已一统天下了,反正A哥知道早在2015年Spring Framework团队就宣布其官网 再也不提供 Jar包的下载;在github上几乎所有的流行的Java项目都用通过Maven来构建和管理的;对于年轻一点的程序员来说,如果一个项目不是Maven项目,大概率不知如何上手,因为上学的时候默认就是按照maven项目来讲的。

如今2021年了,Maven项目是绝对的王者,事实的标准。不客气的说“几乎所有”中大型Java项目都是Maven项目(Spring Boot默认就是Maven项目),这或许是它的最大贡献之一,让全世界的Java开发者们统一了“语言”。Maven的存在也极大的巩固了Java生态,降低管理、构建、依赖管理的门槛,使得一直能以保持活力。

EVvINfV.png!mobile

说到Maven就不得不提一提Gradle。可能有同学会说Gradle会替代Maven成为下一代最流行的项目管理构建工具,不信你看Spring Framework都迁过去用Gradle构建了。诚然Gradle作为新一代产品有很多“过人之处”,但在可预见的将来, Java平台里Maven依旧是绝对的标准 ,无可撼动。毕竟Maven功能非常完善, 关键是没有致命的缺点 ,换的动力并不大的。而且存量市场过于庞大,船大难掉头甚至不会掉头。就像当年的xhtml一直雄心勃勃想干掉html一样,最后,你懂的~

Gradle在Android开发中是主流,因此对于这种“新新技术”采用Gradle是不错的选择

总结

本文介绍了IDEA项目和Eclipse项目的差异,目的是彻底的弄明白二者在项目管理上的区别,不要再人云亦云。

从小了说,本文能帮你解释为毛项目中的xxx.iml,.project等文件都绝对不要提交到github仓库,否则会被罚工资;从大了说本文告诉了你是Maven帮你做到了 屏蔽差异 让项目标准化的,这是不用再关心具体IDEA的底层原因。

说明:在Maven之前是Ant来管理和构建项目,做到统一化。但因Ant有点久远了,所以本文直接以大家更为熟悉的Maven做解答

当然喽,本文并非Maven专题,所以对它的描述也只是一笔带过。Maven的作用 远远不止如此 ,对Maven感兴趣的请移步Maven专栏查看哈。

下篇文章将介绍平时使用IDEA打开maven项目的一个 痛点 问题:Maven项目某些模块无法被IDEA自动识别,如何手动批量导入/识别呢?

本文思考题

本文所属专栏: IDEA ,后台回复专栏名即可获取全部内容,已被 https://www.yourbatman.cn 收录。

看完了不一定懂,看懂了不一定会。来,文末3个思考题帮你复盘:

  1. 如何使用Eclipse创建多“模块”项目?

  2. Maven项目被IDEA和Eclipse加载后,在各自IDE的项目结构上各是什么表现?

  3. 有时候Maven模块无法被IDEA自动发现,那么如何手n动发现Mave模块呢?

推荐阅读

iYZNnaj.gif!mobile
System.out.println("点个赞吧!");
print_r('关注【BAT的乌托邦】!');
var_dump('私聊A哥:fsx1056342982');
console.log("点个赞吧!");
NSLog(@"关注【BAT的乌托邦】!");
print("私聊A哥:fsx1056342982");
echo("点个赞吧!");
cout << "关注【BAT的乌托邦】!" << endl;
printf("私聊A哥:fsx1056342982");
Console.WriteLine("点个赞吧!");
fmt.Println("关注【BAT的乌托邦】!");
Response.Write("私聊A哥:fsx1056342982");
alert("点个赞吧!");

A哥(YourBatman) :Spring Framework开源贡献者,Java架构师,领域专家。文章不标题党,不哗众取宠,每篇文章都成系列去 系统的 攻破一个知识点,每个系列可能是 全网最佳/唯一 。注重基本功修养,底层基础决定上层建筑。现有IDEA系列、Spring N多系列、Bean Validation系列、日期时间系列......关注免费获取

bAFBVbr.png!mobile


Recommend

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK