kafka maven没有下载_构建工具的进化:ant, maven, gradle
在講解基礎(chǔ)知識的過程中,我們也要?jiǎng)邮秩憽6鳭ava發(fā)展到現(xiàn)在,可以幫助我們寫程序,構(gòu)建,發(fā)布的工具有一大堆。今天就來討論一下構(gòu)建工具。在開始之前,我們先講點(diǎn)別的。
如何學(xué)習(xí)琳瑯滿目的框架和工具
學(xué)Java的新人,最頭疼的事情,莫過于工具太多,挑花了眼。不管你要做什么,幾乎都要面臨各種各樣的選擇。我是應(yīng)該選hibernate呢?還是mybatis。我新建一個(gè)工程,要不要加上spring?mvc, tx都是什么?tomcat,jetty是什么?網(wǎng)絡(luò)編程要不要用netty?要在服務(wù)端布署多個(gè)機(jī)器,用akka行不行?DMQ呢?protobuf是什么鬼?類似的問題還有很多。
如果利用搜索引擎,想去看看這些工具分別是干嘛的,會(huì)發(fā)現(xiàn),搜索結(jié)果五花八門,說什么的都有,甚至有些說法都相互矛盾。造成這些亂象的原因,一是Java的應(yīng)用過于廣泛,在不同的軟件體系中都能看到Java的身影,而不同的需求,會(huì)使用不同的工具,甚至是同樣的工具,在不同的環(huán)境下,都會(huì)有不同的用法。二是,Java的流行已經(jīng)有很長時(shí)間了,隨著時(shí)間的推移,肯定會(huì)有很多工具沒有跟上歷史的潮流而慢慢被淘汰。比如J2EE現(xiàn)在的市場占有率只有不足5%。再比如java swing的圖形界面編程,現(xiàn)在幾乎沒有公司再使用swing進(jìn)行圖形界面編程了,最早,互聯(lián)網(wǎng)公司就幾乎沒有采用過swing的方案。swing只在某些企業(yè)級軟件里發(fā)揮作用,而隨著HTML5的興起,越來越多的軟件公司也把自己的界面搬到web前端,現(xiàn)在的html5對2d, 3d都有非常好的支持,而一套簡潔的CSS就能定制出漂亮的界面。所以swing被html5擠出歷史進(jìn)程實(shí)屬正常。再比如JSF,JavaFX等等,也算是出師未捷身先死。有用的,沒用的一堆堆地都堆到新手面前,新手的感覺肯定就是“那叫一個(gè)亂”啊。
說到這里,吐槽一下,某些培訓(xùn)機(jī)構(gòu)和出版機(jī)構(gòu)。為了湊篇幅,還會(huì)把一些已經(jīng)不常用的技術(shù)加上,這就給新手們,尤其是自學(xué)的新手們帶來誤導(dǎo),以為這些東西很重要。例如《Java核心技術(shù)》這本書的第一卷里,還為swing準(zhǔn)備了大段的篇幅,甚至還有awt,而這些東西早就不應(yīng)該被列入學(xué)習(xí)計(jì)劃了。這一點(diǎn)《Java編程思想》會(huì)好一點(diǎn),在第4版里,圖形界面編程已經(jīng)壓縮到最后一章了,做為參考提醒一下讀者,Java里還有這么個(gè)玩意。
關(guān)于這些框架,工具的學(xué)習(xí),我這里有一個(gè)建議:什么都別學(xué),從基礎(chǔ)開始,把根基搞扎實(shí)了。然后自己動(dòng)手做工程,遇到問題了,再去學(xué)習(xí)會(huì)更好。我覺得一個(gè)好的老師,不是手把手地把知識教給你,而是能夠指出問題的所在。我舉一個(gè)例子。我之前指導(dǎo)過一個(gè)師弟學(xué)習(xí)Java,我讓他自己用socket寫一個(gè)web server ,他使用了一個(gè)線程一個(gè)連接的原始的線程方案,并且使用本機(jī)測試,開了十來個(gè)客戶端,覺得還不錯(cuò)。我就告訴他,你這樣的測試是不對的,你要去找一個(gè)client端的benchmark,或者自己寫個(gè)工具,創(chuàng)建成百上千個(gè)連接,然后再看看你的web server的表現(xiàn)如何。后來,他發(fā)現(xiàn),當(dāng)創(chuàng)建幾百個(gè)連接以后,服務(wù)端幾乎就跑不動(dòng)了。然后,我就提醒他,可以考慮一下,業(yè)界有哪些解決方案。這時(shí)候,他找到了nio,netty, 線程池等等方案。然后自己去重構(gòu),重構(gòu)過程中,發(fā)現(xiàn)邏輯和頁面合在一起,很難處理,又引入了spring mvc,為了操作數(shù)據(jù)庫,又引入了hibernate等等。
回顧他學(xué)習(xí)的過程可以發(fā)現(xiàn),對于工具和框架,被動(dòng)地學(xué)習(xí)會(huì)比主動(dòng)地學(xué)習(xí)效果好。到了不得不學(xué)的時(shí)候再去學(xué)習(xí),有具體的場景,學(xué)起來必然事半功倍。我再舉一個(gè)例子,上次在北京和朋友一起吃飯,他抱怨說Java不好招。我說,北京那么多培訓(xùn)班,新人一把一把地,不是隨便招嗎?他就講了自己的面試經(jīng)歷。有一個(gè)小伙子,簡歷上寫了熟悉servlet, spring,ibatis等框架。他就和這個(gè)小伙子聊怎么用這些框架,小伙子答的還可以。然后他就問到了http協(xié)議和Java中的Proxy(這是實(shí)現(xiàn)Spring的核心機(jī)制)以及reflection,小伙子就答不上來了。這就有點(diǎn)舍本逐末了,且不說,是不是所有公司都會(huì)使用spring,就算spring是標(biāo)準(zhǔn)配置,被寫到Java語言標(biāo)準(zhǔn)中去,那也不能基礎(chǔ)太薄弱了,出了詭異BUG,都不知道怎么查。框架這個(gè)東西,遇到問題再去學(xué)吧,如果你跟著框架走,三天兩頭有新的東西出來,你只能疲于奔命。今天出個(gè)rabbitmq,你要學(xué),明天出個(gè)kafka,你還要學(xué),沒準(zhǔn)哪天又出來個(gè)什么樣的新DMQ,你還是得學(xué)。這學(xué)到什么時(shí)候是個(gè)頭了。
回到今天的主題,我們討論三個(gè)構(gòu)建工程用的工具。
構(gòu)建工具
我們要寫一個(gè)Java程序,一般的步驟也就是編譯,測試,打包。這個(gè)構(gòu)建的過程,如果文件比較少,我們可以手動(dòng)使用java, javac, jar命令去做這些事情。但當(dāng)工程越來越大,文件越來越多,這個(gè)事情就不是那么地令人開心了。因?yàn)檫@些命令往往都是很機(jī)械的操作。但是我們可以把機(jī)械的東西交給機(jī)器去做。
在linux上,有一個(gè)工具叫make。我們可以通過編寫Makefile來執(zhí)行工程的構(gòu)建。windows上相應(yīng)的工具是nmake。這個(gè)工具寫起來比較羅嗦,所以從早期,Java的構(gòu)建就沒有選擇它,而是新建了一個(gè)叫做ant的工具。ant的思想和makefile比較像。定義一個(gè)任務(wù),規(guī)定它的依賴,然后就可以通過ant來執(zhí)行這個(gè)任務(wù)了。我們通過例子看一下。下面列出一個(gè)ant工具所使用的build.xml:
<?xml version="1.0" encoding="UTF-8" ?> <project name="HelloWorld" default="run" basedir="."> <property name="src" value="src"/> <property name="dest" value="classes"/> <property name="jarfile" value="hello.jar"/> <target name="init"> <mkdir dir="${dest}"/> </target> <target name="compile" depends="init"> <javac srcdir="${src}" destdir="${dest}"/> </target> <target name="build" depends="compile"> <jar jarfile="${jarfile}" basedir="${dest}"/> </target> <target name="test" depends="build"> <java classname="test.ant.HelloWorld" classpath="${hello_jar}"/> </target> <target name="clean"> <delete dir="${dest}" /> <delete file="${hello_jar}" /> </target> </project>可以看到ant的構(gòu)建腳本還是比較清楚的。ant定義了五個(gè)任務(wù),init, compile, build, test, clean。每個(gè)任務(wù)做什么都定義清楚了。打包之前要先編譯,所以通過depends來指定依賴的路徑。如果在命令行里執(zhí)行ant build,那就會(huì)先執(zhí)行compile,而compile又依賴于init,所以就會(huì)先執(zhí)行init。看起來很合理,對吧?有了這個(gè)東西以后,我們只要一條命令:
ant test就可以執(zhí)行編程,打包,測試了。為開發(fā)者帶來了很大的便利。
但是ant有一個(gè)很致命的缺陷,那就是沒辦法管理依賴。我們一個(gè)工程,要使用很多第三方工具,不同的工具,不同的版本。每次打包都要自己手動(dòng)去把正確的版本拷到lib下面去,不用說,這個(gè)工作既枯燥還特別容易出錯(cuò)。為了解決這個(gè)問題,maven閃亮登場。
maven最核心的改進(jìn)就在于提出倉庫這個(gè)概念。我可以把所有依賴的包,都放到倉庫里去,在我的工程管理文件里,標(biāo)明我需要什么什么包,什么什么版本。在構(gòu)建的時(shí)候,maven就自動(dòng)幫我把這些包打到我的包里來了。我們再也不用操心著自己去管理幾十上百個(gè)jar文件了。
這了達(dá)到這個(gè)目標(biāo),maven提出,要給每個(gè)包都標(biāo)上坐標(biāo),這樣,便于在倉庫里進(jìn)行查找。所以,使用maven構(gòu)建和發(fā)布的包都會(huì)按照這個(gè)約定定義自己的坐標(biāo),例如:
<?xml version="1.0" encoding="utf-8"?>這樣,我就定義了我自己的包的坐標(biāo)是cn.hinus.recruit:Example:0.1.0-SNAPSHOT,而我的工程要依賴junit:junit:4.10。那么maven就會(huì)自動(dòng)去幫我把junit打包進(jìn)來。如果我本地沒有junit,maven還會(huì)幫我去網(wǎng)上下載。下載的地方就是遠(yuǎn)程倉庫,我們可以通過repository標(biāo)簽來指定遠(yuǎn)程倉庫。
maven里拋棄了ant中通過target定義任務(wù)的做法,而是引入了生命周期的概念。這個(gè)問題要講下去,就是一個(gè)大的話題了。我們暫時(shí)放一下。因?yàn)槲覀円唇裉斓淖罱KBOSS,gradle
Gradle
maven已經(jīng)很好了,可以滿足絕大多數(shù)工程的構(gòu)建。那為什么我們還需要新的構(gòu)建工具呢?第一,maven是使用xml進(jìn)行配置的,語法不簡潔。第二,最關(guān)鍵的,maven在約定優(yōu)于配置這條路上走太遠(yuǎn)了。就是說,maven不鼓勵(lì)你自己定義任務(wù),它要求用戶在maven的生命周期中使用插件的方式去工作。這有點(diǎn)像設(shè)計(jì)模式中的模板方法模式。說通俗一點(diǎn),就是我使用maven的話,想靈活地定義自己的任務(wù)是不行的。基于這個(gè)原因,gradle做了很多改進(jìn)。
gradle并不是另起爐灶,它充分地使用了maven的現(xiàn)有資源。繼承了maven中倉庫,坐標(biāo),依賴這些核心概念。文件的布局也和maven相同。但同時(shí),它又繼承了ant中target的概念,我們又可以重新定義自己的任務(wù)了。(gradle中叫做task)
我們來體驗(yàn)一下,新建一個(gè)空目錄,在命令行,執(zhí)行
gradle可以看到新創(chuàng)建了一個(gè)工程,工程根目錄下,有這幾項(xiàng):
build.gradle gradle settings.gradle src我們看一下,build.gradle的內(nèi)容:
// Apply the java plugin to add support for Java內(nèi)容很簡單,引入了java插件,指定倉庫,指定依賴。可以看到依賴的設(shè)定相比起xml的寫法,變得大大簡化了。
使用gradle,任務(wù)又變成了核心概念了。我們就來體驗(yàn)一下任務(wù)。
在build.gradle里添加這樣的任務(wù):
task hello << { println 'welcome to gradle'; }然后在命令行執(zhí)行
gradle -q hello就可以看見打印一行"welcome to gradle"。在使用maven構(gòu)建的時(shí)候,如果想臨時(shí)對某一個(gè)構(gòu)建任務(wù)加一點(diǎn)log,會(huì)是個(gè)非常困難的事情 。但在gradle里,就變得非常簡單,因?yàn)間radle的背后其實(shí)是groovy這個(gè)編程語言在起作用。為了驗(yàn)證這一點(diǎn),我們再改一下:
task然后執(zhí)行g(shù)radle -q hello,就可以看到連續(xù)打印了三行。使用腳本語言進(jìn)行構(gòu)建,這幾乎給了我們?nèi)魏蔚哪芰?#xff0c;我們可以在構(gòu)建的時(shí)候做任何的事情,甚至你可以直接讓gradle幫你做表達(dá)式求值 :)
導(dǎo)入到 IDE
在Java的開發(fā)中,我們不可能脫離集成開發(fā)環(huán)境(Integrated Develop Environment)。因?yàn)镮DE提供了代碼補(bǔ)全和方便的代碼跳轉(zhuǎn),這是普通的文本編輯軟件(比如vim)很難做到的。所以我們還是要通過ide來進(jìn)行代碼開發(fā)。
以前在ide里使用spring的時(shí)候,我們要手動(dòng)下載spring的包,如果spring依賴了其他的第三方的庫,我們還要去下載那個(gè)庫并且添加到IDE中去。現(xiàn)在,我們就不必再這樣做了。只需要在build.gradle里定義好依賴,然后更新它,IDE就可以自動(dòng)幫我們把包導(dǎo)進(jìn)來。
例如,我要在新建的工程里使用spring,只需要在build.gradle里添加一行:
然后,在gradle窗口里,點(diǎn)擊更新:
然后,intellij就自動(dòng)把spring所依賴的所有包都下載下來了。
非常方便。
好了,今天的課程就到這里了。作業(yè):
使用gradle新建一個(gè)工程,并把它導(dǎo)入到你喜歡的IDE中去。添加spring依賴,并更新,觀察一下,gradle的工作方式。
小密圈《進(jìn)擊的Java新人》中,有更詳細(xì)的內(nèi)容,以及我已經(jīng)建好的一個(gè)工程。已經(jīng)加入小密圈的同學(xué)請去git上clone下來,我們接下來的課程會(huì)在這個(gè)工程上寫代碼咯。知乎專欄只負(fù)責(zé)講解知識,不負(fù)責(zé)指導(dǎo)動(dòng)手。
上一節(jié):進(jìn)制習(xí)題課
下一節(jié):Java中的設(shè)計(jì)模式:適配與裝飾
課程目錄:總目錄
總結(jié)
以上是生活随笔為你收集整理的kafka maven没有下载_构建工具的进化:ant, maven, gradle的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 从事IT行业需要的职业技能有哪些
- 下一篇: win10中硬盘如何分区