<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          面試官:Maven 的這 7 個(gè)問題你思考過沒有?

          共 3394字,需瀏覽 7分鐘

           ·

          2021-10-02 03:43

          閱讀本文大概需要 5.5 分鐘。

          來自:https://dwz.cn/PHYFFK27

          現(xiàn)在的項(xiàng)目中 Maven 隨處可見,面試的時(shí)候,經(jīng)常會被問一些項(xiàng)目中 Maven 的問題,但是平時(shí) Maven 項(xiàng)目一般不會出什么問題,可能你不太注意,以下7個(gè)問題,一般說出來并掌握,至少可以證明你 Maven 用的熟練度還可以。
          Maven的倉庫管理、依賴管理、繼承和聚合等特性為項(xiàng)目的構(gòu)建提供了一整套完善的解決方案,如果你搞不懂Maven,那么一個(gè)多模塊的項(xiàng)目足以讓你頭疼,依賴沖突就會讓你不知所措,甚至搞不清楚項(xiàng)目是如何運(yùn)行起來的...
          OK,博主就曾經(jīng)被Maven“傷害”過,所以,我們要:徹底搞定Maven!
          回想一下,當(dāng)你新到一家公司,安裝完JDK后就會安裝配置Maven,很大可能性你需要修改settings.xml文件,比如你會修改本地倉庫地址路徑,比如你很可能會copy一段配置到你的settings.xml中(很可能就是私服的一些配置)。
          接下來,你會到IDEA或者Eclipse中進(jìn)行Maven插件配置,然后你就可以在工程中的pom.xml里面開始添加標(biāo)簽來管理jar包,在Maven規(guī)范的目錄結(jié)構(gòu)下進(jìn)行編寫代碼,最后你會通過插件的方式來進(jìn)行測試、打包(jar or war)、部署、運(yùn)行。
          上面描述了對Maven的一些使用方式,下面我們進(jìn)行一些思考:

          1、本地倉庫?Maven到底有哪些倉庫?它們什么關(guān)系?

          Maven倉庫:
          本地倉庫路徑配置:
          你要jar包,不可能每次都要聯(lián)網(wǎng)去下載吧,多費(fèi)勁,所以本地倉庫就是相當(dāng)于加了一層jar包緩存,先到這里來查。如果這里查不到,那么就去私服上找,如果私服也找不到,那么去中央倉庫去找,找到j(luò)ar后,會把jar的信息同步到私服和本地倉庫中。
          私服,就是公司內(nèi)部局域網(wǎng)的一臺服務(wù)器而已,你想一下,當(dāng)你的工程Project-A依賴別人的Project-B的接口,怎么做呢?沒有Maven的時(shí)候,當(dāng)然是copy Project-B jar到你的本地lib中引入,那么Maven的方式,很顯然需要其他人把Project-B deploy到私服倉庫中供你使用。因此私服中存儲了本公司的內(nèi)部專用的jar!不僅如此,私服還充當(dāng)了中央倉庫的鏡像,說白了就是一個(gè)代理!
          中央倉庫:該倉庫存儲了互聯(lián)網(wǎng)上的jar,由Maven團(tuán)隊(duì)來維護(hù),地址是:http://repo1.maven.org/maven2/。

          2、關(guān)于<dependency>的使用

          依賴管理:
          img_0822_02__4.png
          其實(shí)這個(gè)標(biāo)簽揭示了jar的查找坐標(biāo):groupId、artifactId、version
          一般而言,我們可以到私服上輸入artifactId進(jìn)行搜索,或者到http://search.maven.org/、http://mvnrepository.com/上進(jìn)行查找確定坐標(biāo)。
          version分為開發(fā)版本(Snapshot)和發(fā)布版本(Release),那么為什么要分呢?
          在實(shí)際開發(fā)中,我們經(jīng)常遇到這樣的場景,比如A服務(wù)依賴于B服務(wù),A和B同時(shí)開發(fā),B在開發(fā)中發(fā)現(xiàn)了BUG,修改后,將版本由1.0升級為2.0,那么A必須也跟著在POM.XML中進(jìn)行版本升級。過了幾天后,B又發(fā)現(xiàn)了問題,進(jìn)行修改后升級版本發(fā)布,然后通知A進(jìn)行升級...可以說這是開發(fā)過程中的版本不穩(wěn)定導(dǎo)致了這樣的問題。
          Maven,已經(jīng)替我們想好了解決方案,就是使用Snapshot版本,在開發(fā)過程中B發(fā)布的版本標(biāo)志為Snapshot版本,A進(jìn)行依賴的時(shí)候選擇Snapshot版本,那么每次B發(fā)布的話,會在私服倉庫中,形成帶有時(shí)間戳的Snapshot版本,而A構(gòu)建的時(shí)候會自動下載B最新時(shí)間戳的Snapshot版本!

          3、既然Maven進(jìn)行了依賴管理,為什么還會出現(xiàn)依賴沖突?處理依賴沖突的手段是?

          依賴的版本?
          首先來說,對于Maven而言,同一個(gè)groupId同一個(gè)artifactId下,只能使用一個(gè)version!
          根據(jù)上圖的依賴順序,將使用1.2版本的jar。
          現(xiàn)在,我們可以思考下了,比如工程中需要引入A、B,而A依賴1.0版本的C,B依賴2.0版本的C,那么問題來了,C使用的版本將由引入A、B的順序而定?這顯然不靠譜!如果A的依賴寫在B的依賴后面,將意味著最后引入的是1.0版本的C,很可能在運(yùn)行階段出現(xiàn)類(ClassNotFoundException)、方法(NoSuchMethodError)找不到的錯(cuò)誤(因?yàn)锽使用的是高版本的C)!
          這里其實(shí)涉及到了2個(gè)概念:依賴傳遞(transitive)、Maven的最近依賴策略。
          依賴傳遞:如果A依賴B,B依賴C,那么引入A,意味著B和C都會被引入。
          Maven的最近依賴策略:如果一個(gè)項(xiàng)目依賴相同的groupId、artifactId的多個(gè)版本,那么在依賴樹(mvn dependency:tree)中離項(xiàng)目最近的那個(gè)版本將會被使用。(從這里可以看出Maven是不是有點(diǎn)小問題呢?能不能選擇高版本的進(jìn)行依賴么?據(jù)了解,Gradle就是version+策略)
          現(xiàn)在,我們可以想想如何處理依賴沖突呢?
          想法1:要使用哪個(gè)版本,我們是清楚的,那么能不能不管如何依賴傳遞,都可以進(jìn)行版本鎖定呢?
          使用<dependencyManagement> 這種主要用于子模塊的版本一致性中
          想法2:在依賴傳遞中,能不能去掉我們不想依賴的?
          使用<exclusions>在實(shí)際中我們可以在IDEA中直接利用插件幫助我們生成
          想法3:既然是最近依賴策略,那么我們就直接使用顯式依賴指定版本,那不就是最靠近項(xiàng)目的么?
          使用<dependency>

          4、引入依賴的最佳實(shí)踐,提前發(fā)現(xiàn)問題!

          在工程中,我們避免不了需要加一些依賴,也許加了依賴后運(yùn)行時(shí)才發(fā)現(xiàn)存在依賴沖突在去解決,似乎有點(diǎn)晚!那么能不能提前發(fā)現(xiàn)問題呢?
          如果我們新加入一個(gè)依賴的話,那么先通過mvn dependency:tree命令形成依賴樹,看看我們新加入的依賴,是否存在傳遞依賴,傳遞依賴中是否和依賴樹中的版本存在沖突,如果存在多個(gè)版本沖突,利用上文的方式進(jìn)行解決!

          5、Maven規(guī)范化目錄結(jié)構(gòu)

          這里需要注意2點(diǎn):
          1、src/main下內(nèi)容最終會打包到Jar/War中,而src/test下是測試內(nèi)容,并不會打包進(jìn)去。
          2、src/main/resources中的資源文件會COPY至目標(biāo)目錄,這是Maven的默認(rèn)生命周期中的一個(gè)規(guī)定動作。(想一想,hibernate/mybatis的映射XML需要放入resources下,而不能在放在其他地方了)

          6、Maven的生命周期

          Maven生命周期:
          我們只需要注意一點(diǎn):執(zhí)行后面的命令時(shí),前面的命令自動得到執(zhí)行。
          實(shí)際上,我們最常用的就是這么幾個(gè):
          1、clean:有問題,多清理!2、package:打成Jar or War包,會自動進(jìn)行clean+compile 3、install:將本地工程Jar上傳到本地倉庫 4、deploy:上傳到私服

          7、關(guān)于scope依賴范圍

          既然,Maven的生命周期存在編譯、測試、運(yùn)行這些過程,那么顯然有些依賴只用于測試,比如junit;有些依賴編譯用不到,只有運(yùn)行的時(shí)候才能用到,比如mysql的驅(qū)動包在編譯期就用不到(編譯期用的是JDBC接口),而是在運(yùn)行時(shí)用到的;還有些依賴,編譯期要用到,而運(yùn)行期不需要提供,因?yàn)橛行┤萜饕呀?jīng)提供了,比如servlet-api在tomcat中已經(jīng)提供了,我們只需要的是編譯期提供而已。
          總結(jié)來說:
          1、compile:默認(rèn)的scope,運(yùn)行期有效,需要打入包中。
          2、provided:編譯期有效,運(yùn)行期不需要提供,不會打入包中。
          3、runtime:編譯不需要,在運(yùn)行期有效,需要導(dǎo)入包中。(接口與實(shí)現(xiàn)分離)
          4、test:測試需要,不會打入包中。
          5、system:非本地倉庫引入、存在系統(tǒng)的某個(gè)路徑下的jar。(一般不使用)
          <END>
          瀏覽 40
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  黄色片免费视频草逼草逼草逼草逼草逼 | 日屄福利 | 国产精品秘| 亚洲无码黄色电影 | 国产swag在线播放 |