你好,我是A哥(YourBatman)。
如何給Module模塊單獨(dú)增加依賴?如何知道哪些Module模塊用了Spring框架,哪些是web工程?IDEA如何打Jar包?打War包?
熟練的正確使用IntelliJ IDEA,是一個(gè)“高手”該有的樣子,因?yàn)槟鞘悄愕拈T面。上篇文章 重點(diǎn)介紹了IDEA里最為重要的兩個(gè)概念:Project項(xiàng)目和Module模塊。相信你看完后再也不會(huì)把IDEA的Project比作Eclipse的Workspace,并且對(duì)IDEA有了一份更深的了解。
本文繼續(xù)理解IDEA對(duì)項(xiàng)目、模塊的管理。管理項(xiàng)目是一個(gè)IDEA的基本功能,但往往最基礎(chǔ)的是最重要的更是最容易被忽略的。因此本文是你更好去理解IDEA管理maven結(jié)構(gòu)、gradle結(jié)構(gòu)、Spring Boot項(xiàng)目結(jié)構(gòu)的基礎(chǔ),萬丈高樓平地起,它就是這個(gè)地基。上層結(jié)構(gòu)再怎么繁繁多變,殊途同歸最終都由Project Structure來體現(xiàn),從而給開發(fā)者以幾近相同的編碼體驗(yàn)。

本文提綱

版本約定
IntelliJ IDEA:2020.3.1
正文
Project Structure是一個(gè)你開發(fā)過程中偶爾/經(jīng)常會(huì)打開,但卻很少用心留意的窗口。不同于一般設(shè)置窗口,它和項(xiàng)目的緊密度非常的高且有一定理解難度,若設(shè)置不當(dāng)項(xiàng)目可能無法運(yùn)行甚至無法編碼(比如編譯報(bào)錯(cuò)、jar包找不著等),為此我做件一般人都不愿意做的事,對(duì)它進(jìn)行詳解,相信做難事必有所得。
本文基于上文已搭建好的hello項(xiàng)目案例,繼續(xù)研究其項(xiàng)目結(jié)構(gòu)Project Structure的管理。從結(jié)構(gòu)查看,到修改定制,那么問題來了,如何打開一個(gè)Project項(xiàng)目的結(jié)構(gòu)頁呢?
如何打開Project Structure?
看似一個(gè)簡單的操作,里面其實(shí)蘊(yùn)藏著你對(duì)IDEA Project和Module的理解,否則勢(shì)必不知從哪下手。據(jù)了解,也許你是多年的程序員,也未必知道從哪下手。
按照一般思維,會(huì)鼠標(biāo)選中hello,然后右鍵:
但對(duì)不起,右鍵菜單里并無Project Structure選項(xiàng)。Project Structure顧名思義,是針對(duì)Project維度的結(jié)構(gòu)視窗,而你鼠標(biāo)選中的hello只是個(gè)module,所以自然彈出的是對(duì)此module的操作菜單嘍,而非Project的。也許你可能會(huì)講:我點(diǎn)擊了Open Module Settings也打開了Project Structure視窗呀,是的效果上你可能是打開了但道理并非如此,而僅僅是因?yàn)榘阉鼈z放在了一起(同一視窗)而已。
- ?說明:理解IDEA的Project和Module兩大概念,是對(duì)IDEA進(jìn)行一切操作的基礎(chǔ)。前文已非常詳細(xì)(可能是全網(wǎng)最全)的介紹了它倆,可花幾分鐘前往學(xué)習(xí)。點(diǎn)這里電梯直達(dá)?
三種打開方式
要打開一個(gè)Project的結(jié)構(gòu)展示窗口,至少有如下三種辦法,本文都例舉給你。
1.頂部菜單File -> Project Structure

2.點(diǎn)擊右上角的快捷按鈕

3.快捷鍵方式(推薦)
這是我本人最喜歡的方式,至于快捷鍵是哪個(gè)就看你是如何設(shè)定的嘍,我的快捷鍵是ctrl + shift + alt + s。
- ?啰嗦一句:建議你操作IDEA多用快捷鍵,那會(huì)大大提高編碼的效率,并且看起來像高手。基本上記住50個(gè)左右快捷鍵就夠用了,長期以往成了肌肉記憶后這就是你的核心競爭力之一了?
打開hello項(xiàng)目的結(jié)構(gòu)頁如下圖所示:

解釋:為何不需要鼠標(biāo)選中項(xiàng)目?
對(duì)于這個(gè)動(dòng)作,敏感的你是否有發(fā)現(xiàn):打開項(xiàng)目結(jié)構(gòu)并不需要鼠標(biāo)選中任何東西(快捷鍵隨意使用),也就是說鼠標(biāo)失焦?fàn)顟B(tài)都沒問題,何解呢?
回答這個(gè)問題并不難,前提是你已經(jīng)對(duì)IDEA的Project概念爛熟于胸。一個(gè)Project對(duì)應(yīng)一個(gè)視窗,它們是嚴(yán)格1:1的關(guān)系。換句話講,當(dāng)前視窗就代表著Project,因此操作本視窗頂部菜單欄就肯定是作用在該P(yáng)roject上,又何須專門選中什么呢?再者,Project只是個(gè)邏輯概念,你想選都沒得選中的,所以把視窗當(dāng)作它就好。有沒有覺得,這和Java中的this關(guān)鍵字調(diào)用特別像?
最后,這個(gè)問題的答案是:只要鼠標(biāo)還在IDEA視窗內(nèi)(該視窗是活躍窗口),那么對(duì)Project就永遠(yuǎn)就是“選中”狀態(tài)。
Project Structure項(xiàng)目結(jié)構(gòu)剖析
項(xiàng)目結(jié)構(gòu)視窗已打開,那接下來重點(diǎn)來嘍。可以看到它左邊的“菜單欄”,共分為三個(gè)part:
- Project Settings:項(xiàng)目設(shè)置(最重要),本文詳解
- Platform Settings:平臺(tái)設(shè)置,也叫全局設(shè)置。用于管理SDK們(如JDK、Kotlin的SDK等)、全局庫。
一般來講,全局的JDK都會(huì)配置在此處,比如我因?yàn)榻?jīng)常要做多版本嘗試,就管理了多個(gè)JDK版本

- Problems:問題。一般項(xiàng)目出現(xiàn)了問題都會(huì)在此體現(xiàn)(如依賴不一致問題等等),總之問題數(shù)量一致讓它是0是最優(yōu)的
其中Project Settings里面的每個(gè)標(biāo)簽頁是最常用,最關(guān)心的。下面就對(duì)它的每個(gè)tab頁作出解釋和使用說明。
Project頁情況

此視窗可以看到Project本身的基礎(chǔ)信息。如:名稱、SDK版本、語言等級(jí)等等,比較簡單。
對(duì)于此頁面的元素,多啰嗦幾句:
1.為何是SDK版本而不是JDK版本?答:因?yàn)镮ntelliJ IDEA是JVM平臺(tái)IDEA,不僅僅支持Java還有其它語言如Kotlin,所以寫成SDK更抽象
2.為何指定了SDK還要指定語言等級(jí)?答:因?yàn)镾DK版本并不直接決定語言等級(jí)。如你用的JDK 11,但依舊可以把語言等級(jí)調(diào)為8來進(jìn)行編譯/運(yùn)行
這是集成開發(fā)環(huán)境的優(yōu)勢(shì)所在,輕松對(duì)多環(huán)境進(jìn)行定制化支持
3.SDK和語言等級(jí)Project都可指定,作為全局默認(rèn)
這些配置Module默認(rèn)集成,但可自行修改自己的。比如module 1使用Java 5編譯,module 2使用Java 11編譯,這是允許的
Module頁情況
Module頁可謂是重點(diǎn)中的重點(diǎn),甚至是最重要。畢竟Module作為實(shí)際存在形式,所有的源代碼、配置、依賴等都在這里,因此大有可學(xué)呀。

值得注意:Tests測(cè)試包里面的是可以訪問Sources源碼的,但反過來不行。

每個(gè)模塊都能獨(dú)立管理著自己的依賴,這種關(guān)系在模塊自己的.iml文件中記錄著。
知識(shí)點(diǎn):
- Project創(chuàng)建時(shí)默認(rèn)會(huì)創(chuàng)建一個(gè)同名的Module模塊
- Module默認(rèn)沿用Project的SDK、語言等級(jí)等設(shè)置,當(dāng)然也可自己指定
- 每個(gè)Module可自行管理依賴,可以是二方庫、三方庫......
- 本模塊的依賴情況默認(rèn)存儲(chǔ)在項(xiàng)目的{moduleName}.iml文件里
新增依賴
既然Module可以自行管理依賴,那么如何給該模塊新增依賴呢?
舉個(gè)例子,現(xiàn)在需要向hello模塊增加一個(gè)commons-io jar包依賴,可以點(diǎn)擊Dependencies標(biāo)簽頁左下角的+號(hào),選擇Library:

然后選擇,如果沒有就選擇New Libarary...創(chuàng)建一個(gè)唄(有就直接用就成):

下面分別演示選擇Java和選擇From Maven兩種不同庫的方式:
新建Java依賴庫
New Library新建菜單選項(xiàng)中選擇Java選項(xiàng):

這種方式簡單的講:從你本機(jī)里選擇一個(gè)jar(或者一個(gè)目錄里面包含jar、文檔)就成。優(yōu)點(diǎn)是非常輕便,不依賴網(wǎng)絡(luò),缺點(diǎn)是這些jar必須是你本機(jī)已實(shí)際存在的。
新建Maven依賴庫
New Library新建菜單選項(xiàng)中選擇From Maven選項(xiàng):

輸入GAV(或者關(guān)鍵字查找)就能定位到j(luò)ar,此種方式使用起來其實(shí)非常方便,畢竟maven非常好用嘛。缺點(diǎn)自然就是一般情況下需要都需要依賴于網(wǎng)絡(luò)嘍,除非你本地倉庫已存在對(duì)應(yīng)的jar。
通過這兩種方式各執(zhí)行一次添加新的依賴完成后,再看hello模塊的依賴情況,效果如圖:

既然依賴變化了,自然而然的也會(huì)體現(xiàn)在hello.iml文件里嘍,來看看:

依賴添加進(jìn)來,源代碼里就可以正常使用啦:

依賴作用范圍
在New Library創(chuàng)建依賴的時(shí)候,不管用哪種方式選中后,它都會(huì)彈出這個(gè)窗口讓你選擇此依賴的作用范圍

- Module Library:模塊級(jí)別,只能本模塊使用,別的模塊看都看不見
- Project Library(默認(rèn)選中):項(xiàng)目級(jí)別,該項(xiàng)目下所有的模塊均能看見和選中使用
- Global Library:全局級(jí)別,任何項(xiàng)目均可看見和使用
在本例中commons-io是模塊級(jí)別,commons-lang3是項(xiàng)目級(jí)別。因此hello-client模塊添加依賴時(shí)也是能夠看到commons-lang3這個(gè)依賴的(但看不見commons-io):

Libraries頁情況

當(dāng)某Library是所有/大部分模塊都需要的依賴時(shí),就可以上升為Project級(jí)別的依賴,抽取到Libraries標(biāo)簽頁來統(tǒng)一管理。如圖,因?yàn)樯厦娌襟E創(chuàng)建的commons-lang3是項(xiàng)目級(jí)別的,所以也會(huì)出現(xiàn)在這里。
至于如何創(chuàng)建/添加Project級(jí)別的依賴,這里就不用再贅述了吧,上面【新增依賴】章節(jié)已講得很明白。唯一區(qū)別在該頁面選好后不用再選擇Library的作用范圍了(因?yàn)榫褪荘roject級(jí)別的嘛),取而代之的是讓你選擇作用的模塊:

當(dāng)然嘍,你也可以一個(gè)都不選(點(diǎn)擊cancle),那么該jar只是被創(chuàng)建了,而不作用于任何module模塊。
- ?說明:對(duì)于一個(gè)多模塊的Project來講,建議項(xiàng)目使用的所有Jar都放在這里統(tǒng)一管理,模塊要使用時(shí)直接按需choose就成,而不需要自己再單獨(dú)add,方便統(tǒng)一管理?
Facets頁情況

Facets可理解為用于配置Project項(xiàng)目的框架區(qū),它能看到項(xiàng)目的每個(gè)Module模塊使用的框架、語言等情況,并且還可以對(duì)它們進(jìn)行配置。
比如Spring框架,如果某個(gè)模塊使用了它就可以來這里統(tǒng)一配置。優(yōu)點(diǎn)是你會(huì)發(fā)現(xiàn)借助IDEA強(qiáng)大的功能它都給你想好了哪些地方可配置,你可以更改,讓你實(shí)現(xiàn)配置界面化。除了Spring,其它框架如Hibernate也是如此~
目前支持的Facets(語言/框架)類型有:

模塊對(duì)應(yīng)的Facets IDEA會(huì)自動(dòng)Detection探測(cè),若沒有你也可以手動(dòng)添加。
為了更形象的描述此tab頁的作用,這里搬一個(gè)我自己生產(chǎn)項(xiàng)目來看看實(shí)際效果:

說明:不同的Facet對(duì)應(yīng)的最右端窗口內(nèi)容配置項(xiàng)是不一樣的。
通過此視窗,可以看到你當(dāng)前Project項(xiàng)目,哪些模塊使用了Spring框架,哪些是web項(xiàng)目,一目了然。它有個(gè)非常大的作用就是站在Project的視角對(duì)每個(gè)模塊進(jìn)行整體把控,比如若你發(fā)現(xiàn)有個(gè)模塊不需要是web項(xiàng)目(并不需要對(duì)外提供服務(wù)接口),那鐵定就是多引包了或者職責(zé)不清晰導(dǎo)致的,就可立馬針對(duì)性解決,消除隱患。
在實(shí)際工作中我自己比較頻繁的使用這個(gè)功能,用于對(duì)模塊性質(zhì)的定位,比如如果是普通模塊,絕對(duì)不允許是web工程,如果不需要依賴Spring絕對(duì)不允許成為Spring工程。因?yàn)閲?yán)格控制Jar包依賴、工程性質(zhì)是應(yīng)對(duì)大型項(xiàng)目的有效手段。
當(dāng)然嘍,F(xiàn)acets還有個(gè)作用是讓IDEA編譯器認(rèn)識(shí)你的模塊,比如如果你是個(gè)web模塊,若沒有在Facets里體現(xiàn)出來,那IDEA就不認(rèn)識(shí)你,就無法給你提供web的一些便捷操作了。
Artifacts頁情況
IDEA如何打Jar包?如何打War包? 來,上菜~

在Maven大行其道的今天,雖然用IDEA打包很少使用了,但是有些時(shí)候它對(duì)你本地調(diào)試還是蠻有用的,并且對(duì)理解maven的打包依舊有效,來,了解一下。
Artifacts這個(gè)概念不是特別好理解,artifact是maven里的一個(gè)概念,被IDEA借鑒過來。表示某個(gè)模塊要何種打包形式,如jar、war exploded、war、ear等等。Artifact是一個(gè)項(xiàng)目資源的組合體,整合編譯后的 java 文件,資源文件等。有不同的整合方式,比如jar、war、war exploded等等,對(duì)于一個(gè)module而言,有了Artifact就可以部署了,類似于maven的package打包。
- ?說明:war 和 war exploded區(qū)別就是后者不壓縮,開發(fā)時(shí)選后者便于實(shí)時(shí)看到修改文件后的效果?
來個(gè)栗子,這里演示下將hello模塊打包成一個(gè)Jar:

配置好后,只需頂部菜單欄Build -> Build Artifacts,就可以打出這個(gè)Jar包:
執(zhí)行完此命令后,在Output Directory里就能看到hello.jar這個(gè)打包好的文件啦。然后java -jar .\hello.jar就能運(yùn)行嘍(因?yàn)樵蹅兇虻氖强蓤?zhí)行Jar包)。關(guān)于使用IDEA打包還包括打可執(zhí)行jar包、Fatjar、包外引用jar包等等,這里就不展開了,后面會(huì)放在單獨(dú)文章里把各種方式匯總在一起聊聊。
總的來說,無論配置Facets還是Artifacts,都是Intellij IDEA要求我們來做的(雖然有些可自動(dòng)識(shí)別),目的是以便其能識(shí)別這些文件并整合各插件實(shí)現(xiàn)功能(如自動(dòng)化配置、自動(dòng)打包),一切為了編碼體驗(yàn)和編碼效率。
模塊如何依賴其它Module
一個(gè)中大型項(xiàng)目一般有多個(gè)模塊,它們各司其職。模塊與模塊之間一般都存在依賴關(guān)系,比如常見的xxx-core模塊一般會(huì)被其它幾乎所有模塊所依賴。模塊依賴外部庫Library知道怎么搞了,那么如何增加本項(xiàng)目的模塊依賴呢?
其實(shí)道理和步驟基本一樣,比如hello-core模塊里有個(gè)Person類:

hello-service模塊也需要用到Person類及其功能,那么就需要把hello-core模塊依賴進(jìn)來,操作步驟如下:
添加Dependency依賴時(shí),請(qǐng)選擇Module Dependency...選項(xiàng):

選擇本項(xiàng)目中需要依賴進(jìn)來的模塊:

選中hello-core模塊把它依賴到hello-service里來:

點(diǎn)擊ok,搞定了。對(duì)應(yīng)的,此依賴關(guān)系也會(huì)體現(xiàn)在hello-service.iml這個(gè)配置文件上:

如此,我們就可以在hello-service模塊里正常使用Person類啦:
public static void main(String[] args) {
System.out.println(new Person());
}
完美。
總結(jié)
本文對(duì)IntelliJ IDEA的項(xiàng)目結(jié)構(gòu)Project Structure的每個(gè)tab頁進(jìn)行了全面分析,據(jù)我短淺的目光所及,可能是全網(wǎng)獨(dú)一份寫這個(gè)內(nèi)容的。很多同學(xué)覺得IntelliJ IDEA不需要專門的學(xué)習(xí)分析,會(huì)用它導(dǎo)入maven項(xiàng)目,跑跑main函數(shù)啟動(dòng)下Spring Boot就成啦,我卻不以為然。
衡量一個(gè)新手和一個(gè)高手的差異不是順風(fēng)順?biāo)畷r(shí),而是遇到問題時(shí)誰能夠快速解決,誰又只能望洋興嘆,相信薪資的差異也體現(xiàn)在此。我見過的“高手”對(duì)自己最常用的工具用得都是很666的,這不正是技術(shù)范該有的樣子麼?說到底,我們不可能認(rèn)為用一指禪敲代碼的人會(huì)是大牛嘛~
好啦,關(guān)于IDEA的話題暫且先聊到這。其實(shí)我想到的主題還有好幾個(gè),如:
- IDEA如何主動(dòng)去識(shí)別導(dǎo)入不能被自動(dòng)識(shí)別的Maven項(xiàng)目?原理是什么呢?
- IDEA如何打可執(zhí)行Jar包?又如何打FatJar?如何打 包外Jar包(散包) 呢?
- IDEA如何巧用其最新的Http Client腳本能力,結(jié)合對(duì)Controller的嗅探快速完成本地測(cè)試?
- ......
本文思考題
本文已被https://www.yourbatman.cn收錄。
原文地址:https://mp.weixin.qq.com/s/j_yIiXvNlp7JMZaVO1FSrA