IDEA開發java web項目:在多個git倉庫,多個模塊下,IDEA build,debug以及maven package等各種問題

背景

我們最近在開發一個Java web項目,當時的設計基本是這樣:將各個基礎檔案或者其它應用按照模塊劃分,基本上是一個檔案對應一個git倉庫(也有一個git下面有多個maven模塊,這樣的也有),按照職責劃分開,希望將來能夠按照微服務進行拆分(每個模塊都會有api,domain,web層),但是暫時並不會這樣做,也沒有用springboot,常規的war包項目。而且設計上會有一個啓動器,由一個啓動器來控制要依賴哪些模塊並且把它們啓動,不同的啓動器所包含的內容會不一樣,但它們之間也會有共同使用的一些模塊。

最後創建了大約有十餘個git倉庫,也有十個左右的開發,然後基本上每個開發會參與其中的一些(大於等於二,一個啓動器+幾個模塊)。使用IDEA開發,基本上會在同一個工作空間(這個我指的是一個IDEA窗口)裏面會導入多個git項目,通過maven視圖的添加按鈕添加進來的,這樣開發的話,就會使用到本地最新的代碼去編譯測試,測試完了以後是需要deploy到遠程倉庫,供其他人和構建測試環境使用。

基本問題

我剛開始並沒有參與設計和開發,最近加入了,不過我先是梳理十幾個Git倉庫之間的關係,因此把所有的代碼拉取下來並加入到IDEA的一個工作空間內(注意有的項目代碼,是我很久之前已經拉下來了),之後我在啓動項目的過程當中碰見了兩個問題:

假設有3個工程吧,A是啓動工程,A依賴了B和C。

問題1: 本地啓動,報錯;發在羣裏面問一下,這是誰負責的,應該怎麼處理。有人告訴我應該去拉取一下項目B的代碼,然後build一下,再啓動。我試了一下,果然好了。
關於這個問題,我當時就非常鬱悶,我啓動的時候,爲什麼要用本地工作空間的代碼編譯啓動?爲什麼沒有用maven倉庫的。而且在之間羣裏面,隱約記得,有好幾次有這種問題,解決方案都是如此。
我在意的有兩點:

  1. 我並不關心項目B,我也沒有修改它,因此我不需要也不應該操作它。我啓動工程就不應該去拉取B的代碼,我用最新的倉庫裏面的就行了呀。
  2. 默認啓動的話,爲什麼用的是工作空間的,而不是倉庫的。

我拋出了這樣的問題,並且想去查看一下爲什麼。當然得到了一個比較錯誤的結論,是因爲對方導入idea的方式有問題,並且讓對方按照我的來。在這個過程裏面,而且我用maven package的時候,發現打出來的依賴包,居然不是最新的,是因爲對方並沒有deploy。基於這兩點,我以爲回答了上面的這兩個問題。

後來,我又碰到了一個問題,讓我知道了我理解的有問題,並且這個問題很重要,必須要徹底搞清楚。
問題2: 我後面啓動的時候,報錯,一個類找不到,是C工程裏面,我下意識的進行了一系列操作:拉代碼,build,啓動,錯誤仍然還在。最新的代碼裏面,有那個類,沒有問題。然後我又查看了A工程target目錄中的c.jar,發現裏面確實沒有。我又進一步查看了本地和遠程maven倉庫,發現都沒有問題。那麼問題來了,這個錯誤的c.jar到底是從哪裏來的?一定要找到問題,一頓操作,發現是在c工程目錄下的target/classes下面,並沒有那個類的class文件。
哇哦,原來如此。說明IDEA在啓動A的時候,處理C依賴的時候,用了C工程target目錄下的相關文件用於打包,而且它並沒有用C的源碼去編譯,當然也就沒有使用maven倉庫裏面的了。
那顯然我自己的導入方式也是不正確的,因此就展開了一系列的研究,我覺得非常有必要去搞清楚這個問題,肯定可以提高開發效率。

明確目標

我爲什麼要去研究這個呢?我希望是這樣一種場景:十幾個人開發同一個項目,分爲好多模塊,各自負責各自的就行,但是負責的模塊裏面肯定也會有交集,當別人正確的修改完模塊B的代碼以後,發佈到遠程倉庫裏面,其它人啓動的時候,都應該直接用遠程倉庫的(儘管自己本地也有這個模塊),這樣就不會有任何問題(排除他本身提交的錯誤的情況),同時我們自己在做開發的時候,本地測試的時候,編譯使用的應該就是本地的,並且在測試完成後,發佈的倉庫中以後,它本身也可以用倉庫中的進行測試,保證倉庫中那個的也是沒有問題的,這樣別人甚至搭建的環境中的是沒有問題的。當然,這些都建立在所有開發都遵循我們的開發規範,這樣也就可以節省很多不必要的時間了。而且在整個過程當中,所有的項目都是在同一個工作空間的,我不需要對它們進行移除和添加操作。
剛纔說的是做這件事情的原因,那如何來實現這件事情呢?基本上當時是有如下的目標:

  1. IDEA在debug或者run的時候,會先build,或者build也可以單獨執行,那麼這個build到底是如何來區分用工作空間中的還是倉庫?到底是在哪裏配置的,我們能不能手動修改,然後自己來控制?雖然我當時見到的全是使用工作空間的,但很明顯有一個現象,我把工程B移除了工作空間,它就會使用倉庫的,我想那肯定是有配置的。
  2. 在IDEA中的maven倉庫中的clean,compile以及package等命令,與IDEA的build命令到底有什麼關係?或者它們分別做了什麼事情?

這是兩個比較大的目標,但是在實際過程執行的時候,其實也幫助我弄清楚了一些其它小問題,比如maven倉庫中關於快照版本的處理方式,build的時候,有時候會構建,有時候不構建,它到底是怎麼判斷的?package結束了,直接build的時候,有時候沒有任何變化,但有的時候就會有變化,這是爲什麼?如果當不變化的時候,意味着你用的代碼是最新的倉庫裏面的,並不是你本地的,但是你可能不知道。而且還發現了IDEA的關於Build的源碼在哪裏,處理jar或者resources的是哪個類,當然沒有仔細看,還不至於到那一步。

有時候會覺得整個過程特別玄幻,基本上就是大量的測試,採用控制變量法,不斷的去觀察記錄現象,好不容易得出一個結論,過一會兒現象就會推翻之前的結論,然後一度懷疑人生~

關於maven的快照版本:SNAPSHOT

這個我簡單說一下,詳細的可以去查詢資料。
快照版本的出現就是用來解決在開發態會不定期高頻率更新代碼的場景的。
使用的發行版本的話,只要本地有,就不會去遠程倉庫拉,除非把本地的刪除。加參數-U也沒用。
想要拉取最新代碼,就必須更新版本,其實就是升級版本,1.0.0升級到1.0.1。對於開發者和使用者都一樣。
那麼快照版本的話,就允許在同一個版本下,提交無數次快照版本,並且快照版本和發佈版本會放在maven倉庫的不同地方,區別處理,只要不帶SNAPSHOT的都是發行版本。
快照版本它會以時間戳+提交次數命名。因此當我們依賴快照版本的時候,打出來的依賴Jar包一般都是帶時間戳的,當然肯定可以處理一下,比如按照如下配置一下插件:

<plugin>
	<artifactId>maven-war-plugin</artifactId>
	<version>2.6</version>
	<configuration>
		<outputFileNameMapping>@{artifactId}@-@{baseVersion}@.@{extension}@</outputFileNameMapping>
	</configuration>
</plugin>

那不配置上面的插件,行不行呢?我只能說,可能行,因爲在開發態的時候,一定會影響使用;但是僅僅用maven打包的話,可能是不會有影響的。

爲什麼要去研究這個呢?我當時發現了一個問題:最後打出來的文件,WEB-INFO/lib目錄下的jar包,所有快照版本的jar包,都出現了兩次,一個正常的,一個帶時間戳的。並且這兩個jar包是不一樣的,這個我指的是jar包的內容,包含的文件都會有所區別,jar包大小也不一樣。假如說其中一個是舊的,並且在使用的時候,類加載器加載到了舊的類,那顯示問題就出現了,我就是碰見了這個問題。

爲了查看這兩個jar包怎麼來的,也是費了不少的事情,前面一直重現不了,重現的時候,得出的結論又被推翻了,我就直接說一下結論吧。
帶時間戳的是maven進行package命令的時候產生的;
正常的是IDEA在Build的時候產生的;
上面那個插件處理也是maven的插件,當配置完了以後,兩者所產生的jar包就會重複了,如果我們在開發的時候,反覆package以及build,那麼很幸運的是,它們可能會反覆地進行替換,你一定都不知道現在用的是哪個工具打出來的包。爲什麼是可能呢?關鍵在於build的執行原則是:僅build變化的,當沒有變化的時候,它什麼都不幹。關於怎麼來區分變化,這是個重點,後面詳細說一下吧。

快照版本的出現就是爲了爲了方便快捷地在開發階段不更新pom文件的情況下更新最新的依賴。因此它也會有一個更新策略,叫做updatePolicy,用來配置maven從遠程倉庫檢查更新的頻率,默認的值爲daily,表示每天檢查一次,這個在maven的setting文件裏面:

<snapshots>
	<enabled>true</enabled>
	<updatePolicy>always</updatePolicy>
</snapshots>

上面配置的是always,代表的就是每次都強制更新。
或者在執行maven命令的時候,加上-U,代表這次執行也是強制更新。
或者在IDEA裏面也可以配置,當然,肯定是推薦這個了,如下圖:
在這裏插入圖片描述
把這個勾上就行了,然後在IDEA中使用maven的功能就行了。我還稍微研究了一下,加上這個到底有什麼影響,其實就是加了一個參數:

--update-snapshots 

雖然不是-U,因爲在執行maven命令的時候並不是直接執行的,而且執行了IDEA中的某個類,由那個類去間接執行的,怎麼看的呢?當你執行命令的時候,控制檯會打一行日誌:
在這裏插入圖片描述
看這個圖還是比較明確的。關於快照的時候就到這邊吧。

在IDEA中執行maven命令

直接說結論吧,在IDEA中執行maven命令:
在這裏插入圖片描述
就是上述命令,和在命令行裏面執行maven命令,效果是完全一致是:

mvn -U clean compile package -P test

這一點非常肯定。
而且在IDEA裏面執行package的時候,依賴打包的時候一定用的是倉庫的,它一定不會用工作空間裏面。這一點按照正常邏輯也可以想明白:IDEA裏面執行maven===在命令行執行maven,那麼對於maven而已,它根本不知道有IDEA的工作空間這回事。
package用的是倉庫的,build不一定用,所以可能會衝突。

maven的離線工作模式(work offline)

這個東西,和我整體描述的沒有太大關係,只不過順便研究了一下,我曾以爲它對我的研究有所幹擾,後來發現完全沒有。但是這個在我們工作當中,也會有一些作用。
開啓離線模式的話,我們在用maven命令打包的時候,用的都是本地倉庫中,它不會去拉取遠程倉庫中最新的。
啥時候可以用呢?就是,我們僅僅想打個包,不想去拉遠程倉庫的最新包,而且比較明確的是,本地倉庫的就是最新的,畢竟拉取遠程倉庫的是比較慢的。
在IDEA裏面有兩種切換離線模式的方式:
在這裏插入圖片描述
在這裏插入圖片描述

IDEA在build的時候,到底選擇的是工作空間還是倉庫的?

終於到重點了,怎麼發現的,過程就不多說了,重點還是說一下結論吧。

artifacts文件的發現與查看

IDEA在build的時候,它是根據artifacts進行構建的。artifacts裏面定義了各種要構建的目標目標和目標文件,非常詳細,它會按照其中的每一個條目去執行。
(至於artifacts這個概念以及更加詳細的作用,可以在網上自行查詢,我這邊只講解其中一部分)
artifacts文件在我們增加一個Tomcat Server類型的Run/Debug Configurations的時候,會自動創建。
它就是項目中目錄下“./idea/artifacts/project_A_war_exploded.xml”,就是這個xml文件,大家可以自行去查看和打開這個文件。
在這裏插入圖片描述
在這個xml裏面,重點看一下關於依賴jar的不同展現形式吧:

<element id="library" level="project" name="Maven: com.alibaba:fastjson:1.2.17" />

id=library的,這種指的是依賴的倉庫中的,並且是發行(RELEASE)版本。

<element id="file-copy" path="$MAVEN_REPOSITORY$/com/test/project-b/1.0.0-SNAPSHOT/project-b-1.0.0-20200104.063052-16.jar" output-file-name="project-b-1.0.0-SNAPSHOT.jar" />

id=file-copy的,這種指的是依賴的倉庫中的,但是這個特指的快照版本,也能夠看到它本身依賴的是本地倉庫中的某個具體快照版本,具體上可以斷定build的時候就會直接拷貝過來,就是一種綁定關係,這個也會在build的時候判斷更新的時候也會用到。

<element id="archive" name="project-b-1.0.0-SNAPSHOT.jar">
 	<element id="module-output" name="project-b" />
</element>

id=archive的,它在這邊基本上是代表輸出一個jar包,在裏面的元素就是意味着這個jar包裏面有哪些內容了。比如上面這種的,id=module-output的,意思也很明確,就是用name這個模塊的輸出。這種的配置就是用的工作空間中的代碼。

對於這3中情況,它也對應了3中不同依賴的jar包的生成方式。
file-copy和library,基本上就是從本地倉庫直接拷貝過去的。
archive會用模塊的輸出,也就是target下面的classess目錄下的文件去打包生成jar包。

當我發現這些的時候,我感覺已經成功了一大半了,找到了。那就是archive與file-copy的區別了。
當然這些也都是自動生成的,我也研究了一下IDEA是如何更新這些文件的。比如我把B工程從工作空間移除:
在這裏插入圖片描述
移除以後,它會自己刷新一下,但它並沒有修改artifacts文件,當時爲這個事情,頭疼了好久,我在不斷反覆添加和移除,發現有的時候會修改,有的時候沒有修改,難受死了。
當你移除或者添加以後,可以再點擊一下,Reimport按鈕
在這裏插入圖片描述
然後它就會自動對archive和file-copy進行更新了。
研究這個文件更新,花費了不少心血,也研究了一下ignore某個工程的作用,它不會修改文件,但是用可視化工具打開的時候,會有紅字錯誤提示,但build也會成功,只不過會少一個jar包。笑哭臉。

artifacts文件的手動更改

知道了幾種元素的區別,那你就可以手動修改了。可以直接修改文件。
也有一種方式,它本身也提供了可視化工具。
File-Project Structure:Artifacts
點擊exploded,右側就會可視化那個xml,
在這裏插入圖片描述
注意在右側可以在lib下面找出那3種不同的展現形式,同時也可以右擊對元素進行增刪改。
如果要添加工作空間的模塊輸出的話,注意先添加一個archive,名字起成jar包的名稱,然後裏面加一個module output就行了。
如果要添加file-copy的,選擇file,會打開文件瀏覽器,就直接選擇到本地倉庫中的一個具體的jar包,把它們關聯起來。
在這裏插入圖片描述

它能做什麼呢?

回到我遇到的問題,顯然就是,當我把所有工程添加進來的時候,它build的時候,用的就是工作空間的,這個時候,我可能不想用工作空間的,因爲需要我一直拉最新的代碼。那麼我就想用倉庫的,那麼我把它由module-output改成file-copy就行了。

它的價值到底有多大?

本來我覺得這個價值非常大,但是不幸的是,我剛纔說了reimport的時候IDEA會修改artifacts文件,而且我也做了一下測試,我把module-output修改成file-copy,直接去reimport,不去移除項目或者添加的,尷尬的是,它居然給改回去了,又成了module-output。而且重點是,reimport是一個高頻操作。這就很無語了。
如果在這種情況下,還要堅持按照我上面說的做的話,那麼比較好的方式就是改完以後,把相關的內容複製保存下來,你記得在reimport以後,手動修改一下,然後就可以了。可問題是,這樣麻煩不?還是有點兒麻煩呀。
但是如果是相對於,你啓動報錯,問別人,別人看看,告訴你應該怎麼做,這種情況來說,還是非常值得的。而且我也碰見了就算你拉代碼,就不一定可以解決的場景,下面會重點說一下。

那還有沒有其它的辦法呢?來控制到底使用哪裏的代碼呢?仔細研究了build的更新策略以後,我覺得是可以通過一系列嚴格順序的操作來完成的。不需要手動修改artifacts文件的。後面說一下。

build的時候,到底是怎麼判斷,哪些文件是需要或者不需要build的。

上面講的所有的內容,基本上才解決了我的第一個問題,我不想通過拉取本部應該我拉取的代碼來解決這個問題。還有其它問題,build的更新策略是怎麼樣的,build與package等命令的關係與區別。

build與package等maven命令

說實話,build是IDEA的,package是maven的,它們之間沒有任何直接關係。、
要非說間接關係的話,那還真有一點

  1. maven的clean以及compile命令,可能會在build的更新策略造成一定的影響。
  2. 它們之間會有相同的輸出產物,因此會存在一種覆蓋關係,這麼說吧,package一定會覆蓋build的產物,而build不一定。

關於這兩點,接下來通過build的更新策略解釋一下可能會比較合適。

build的更新策略

關於build的策略,一句話很簡單:僅build更新的那部分。
但是太抽象了,一點都不具體,也沒法在實際工作中產生巨大價值;最起碼要解決我們可能會遇到的一個問題,先build,再package,再build,第二次build的時候,發現沒有更新,所以不會有任何變化。因此打出來的包,是倉庫裏面的,並不是我們本地生成的,但我們可能會以爲是我們本地的。
更新策略的話,我這邊直接上結論了,我也測試過,如果有其他看法,可以討論驗證一下。先看一張簡圖:
在這裏插入圖片描述
我們在Build的時候,會在WEB-INF下面生成classes目錄和lib目錄,一般也會重點關注一下這兩個。
在classes下面一把分爲類文件和資源文件,針對資源文件,先不探討了,後面有機會再說。
對於class文件的話,它對應的就是這個工程src/man/java目錄下的文件了,它的更新策略就是判斷原始java文件有沒有更新過。
lib目錄下都是依賴的jar包,但是我們也可以分爲兩種,依賴本地模塊和倉庫的,前者可以認爲是我們自己也一直開發的,後者完全就是別人的。對於我們自己開發的,也會分爲兩種,一種是本地模塊輸出,一種是本地倉庫拷貝。
那麼基本上就是3種情況,對於在倉庫中的,那就是判斷倉庫中的jar包有沒有更新了,這是比較簡單了。
關鍵在於本地模塊輸出的,比如依賴了B,它判斷要不要更新的依據就是,B/target目錄下的classes中的class文件有沒有被更新。它應該會記錄上一次build的時候,target下面的文件狀態。這個結果和它的描述也是有點兒聯繫的,這種的在artifacts文件中稱之爲:module-output,模塊輸出,那不就是模塊中的target嗎?而且我也反覆測試過,修改過java類,修改過class文件等等。
基本上當target(或者classes)整個目錄不存在的話,它會

A依賴的是B的target,那B的target呢,當然是B的源碼了。
但是buildA的時候,並不會buildB(在B的target目錄存在的時候),所以我們可能需要單獨buildB了。

瞭解了build的更新策略,帶給我們的價值是什麼?

知道了上述以後,可以解釋得通,我碰見的第二個問題了。
所有能猜到的地方,都是最新的代碼,但是Build出來的包就是舊的。就是因爲target下面缺了一個類文件,而且我沒有更新過它。
如果我選擇使用倉庫中的,那就不會有這個問題了。按照上面講的去修改artifacts文件了。
但是肯定會有更多的場景是需要使用本地模塊的文件的,那麼基於上面得出的結論,我們要怎麼做呢。
那就是持續更新某個工程的target目錄,也就是需要clean以及compile,或者直接clean掉就行了,build的時候會自動compile。
但是如果說我們使用IDEA開發的時候,修改完java,不是基本上就會自動編譯了嘛,那上面豈不是就白說了。這種情況下,還真的是。
那基本上就是針對在非IDEA環境下拉取代碼的時候,如果想用本地的話,就去clean一下。或者針對那個工程build一下。
實在是不想費這個勁去思考到底怎麼更新的話,可以選擇rebuild,這個操作是強制Build,先clean然後build。而且rebuild A的時候,也會把B順便rebuild了,是不是很強大的功能,但是缺點也很明顯,費時間啊。肯定不會每次都這樣做的。

利用build的更新策略,來控制啓動的時候用的jar包到底是工作空間的代碼產生的,還是倉庫的。

明確一點,我們使用IDEA啓動工程,一定會build。
還是A依賴B,就討論B。
下面的討論,建立在不修改artifacts文件的情況下。修改的話,就會破壞默認的配置。
那麼怎麼確認我們用本地工作空間的代碼呢?
永遠不使用maven的package功能。每次啓動僅Build,或者build之前clean一下B工程,保證可以拿到最新的本地工作空間的代碼打出來的jar包。
那麼怎麼確認來使用倉庫中的呢?
根據上面的所有討論,有下面幾個事實:

  1. maven的package功能一定會用倉庫中的。
  2. 啓動工程的時候,一定會用到build功能。
  3. 默認情況下,build功能會使用的工作空間中的代碼進行打包。

既然要使用倉庫的,那一定要用maven的package功能,而且之後的build不能覆蓋package的結果。
默認的build功能,它僅編譯,不打包,但是可以配置讓它也打包:
在這裏插入圖片描述
勾選上就行了,做這個事情是爲了每次只需要僅僅build就行了,而不用debug或者run去打包,然後再停下來。
關鍵的步驟來了,
對A工程進行build或者rebuild,僅僅對這個工程就行了,不需要對整個工作空間Build。
然後去package,僅僅package,不要clean。
然後直接啓動,這樣打出來的包,一定用的是倉庫的。
第一次的build是爲了第二次的build不去覆蓋package的結果。

其實在開發過程中,更多的場景是一部分用本地的(比如B工程),其它的用倉庫的(但是工作空間中也有)。也可以做。
還是按照上面的,先build,然後package,然後把B工程clean一下,然後啓動A。這樣A一定用的是你本地的。
我覺得這種操作方式不錯。

實際的價值在哪裏?

等寫到這裏的時候,我甚至有點兒懷疑了,它產生的價值到底大不大呢?我內心最直接的感覺是好像對各種操作更加了解了,但是總感覺缺了點什麼,那就是非常明確直觀的開發規範,能夠直接對開發過程產生積極影響的做法,必須要輸出。

關於開發過程的思考

從一剛開始我來研究這個問題,根本原因是我認爲整個開發過程不順暢,會做一些無用功,我應該去捋一捋順一順這件事情。因爲在人很多,開發週期很長的情況,任何低效率無用的開發都會產生不小的負面作用,影響到開發進度。而且我還發現了開發過程中的其它問題,比如:
A依賴了B,C,D。而C依賴了D。
第一個人只關心,A,B,C。
第二個人只關心,A,B,D。
第二個人修改了B和D,測試通過後,提交了。第一個人拉取了代碼,B報錯了,問第二個人應該怎麼辦,說要把D添加進工作空間裏面,就可以解決這個問題。第一個人也做了,好了。
可問題是,爲什麼要這樣做呢?這不是搞笑呢嘛。當然這個事情和上面討論的,沒有關係。
開發規範的話,就是應該在項目初期訂好,中間也可以增加,所有的開發都必須嚴格按照開發規範執行,對自己,對他人,對項目負責。
那我研究了上面這個東西,肯定也要輸出一些正確的開發規範。

具體的開發規範

還是以我們這個項目爲例,十幾個git,每個人負責一些。
(這種場景和一個git下面,十幾個模塊的,不一樣。一個git的會非常簡單)

  1. 所有人開發測試完的代碼,都必須及時提交,並且要及時deploy到maven的遠程倉庫(可以除過啓動器,這個一定用的是本地的);你自己用的本地代碼開發測試的,但是並不代表別人也用的本地的,或者說其它開發更希望用的是倉庫裏面的,因爲它本身就不關心這個。而且我們構建的測試環境使用的一定是倉庫裏面的,否則可能經常會出現:本地沒有問題,測試環境就出了問題。
  2. deploy結束以後,一定要使用拉取遠程倉庫裏面的包,測試一下,保證遠程倉庫裏面的沒有問題。這個測試有兩種層面,一種看一下只要是最新的就行,可以通過時間戳以及大小來判斷,或者也可以真正跑起來,驗證一下。
  3. 如果你自己的工作空間裏面僅僅導入了你所負責的工程,那麼在整個過程當中,不需要使用package功能,這樣你每次啓動就是使用的就是本地的,不會是遠程倉庫的。而其餘的你不關心的,就會默認使用倉庫裏面的。
  4. 如果你打算使用工作空間裏面,並且向保證每次使用最新的,可以在啓動前,clean一下,注意,clean的是被依賴的那個,比如A依賴B,clean B,然後在啓動。一定是最新的,防止意外情況出現。
  5. 上面的場景都比較簡單,可能也不是常見的。常見的肯定就是下面這種的:你負責A,B,C,D,4個工程,A依賴於其它的,並且全部導入進來了,並且別人也會更新BCD。而且此時此刻你正在修改B,別人修改了B和C,B和C都提交和deploy了,但是你只更新了B,如果此時此刻,你用工作空間跑起來,顯然,一定會出錯,因爲你並沒有最新的C。這裏面的錯可能會分爲兩種,編譯錯誤和運行錯誤,如果是編譯錯誤,那麼你可能是不是必須拉一下C的代碼了?因爲你關心的B都編譯失敗了。要是C沒有在你的工作空間裏面還好說,但是它在,確實挺尷尬的。關於編譯錯誤的正確解決方案,後面在研究一下,看看會不會有更好的。關於運行態的問題,你只要保證C是遠程倉庫的,那就一定沒有問題。具體從操作步驟的話,就是:build A,package A,clean B,debug A。這樣B一定是本地的,其餘的都是遠程倉庫的。
  6. 如果開發過程中, 你發現了一些錯誤,別人給你的解決方案,你認爲是不正確的,不合理的,那就應該提出來,並且一起探討出來合理的做法,如果僅僅拋出問題,不解決的話,那還不如不拋。共同來促進開發。這一點是開發的意識,比上面所有的步驟都重要。

由本地研究IDEA而引出的關於黑箱子的思考

黑箱子,對你而言,你給它輸入,它就給你期待的輸出,你也不關心它是怎麼做的。黑箱子,生活中到處都是。
關於對工作中的黑箱子,我的態度都是比較明確的。
黑箱子是爲了更好的輔助我的工作,在正常情況下,我不需要關心它是如何工作的,內部做了什麼,只要它不對我的工作產生負面的影響。
所以分界線就是:對我的工作有沒有產生負面影響。
那麼一旦產生了影響,那我就需要去思考一些問題,是不是我的操作不對導致的,那麼正確的操作是什麼,這些操作下去,它到底做了什麼,這些問題必須搞清楚,搞到什麼程度呢?搞到你可以確信這裏不會影響到你了就行。
一直研究這個,也找到了IDEA源碼中具體的處理Build的相關類代碼了,但是並沒有進一步看,因爲還沒有到那一步,或許將來會去看。
或者這是不是工具本身的Bug,那這種情況下,是不是就要考慮用其它的方式或者換個黑盒子了?

但是各種的主流框架,不嚴格來說,它也算,它從輸入輸出的角度來講,和工具都是一樣的,你必須要會用它,在不影響你使用的情況下,你也可以不去研究。但是或許有一點不同,框架裏面的原理和具體實現,學到了,我們可以學以致用。但普通的工具,或許沒有這種價值。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章