解決maven多模塊之間的相互依賴的方案


近期在做一個普通javaweb項目轉轉換成maven項目的任務。

原項目類型:javaWeb項目

兩個源碼包一個產品基礎包,一個基於產品基礎包的開發包,兩個都是普通javaWeb項目。本來應該是開發包可以單邊引用產品基礎包的,由於開發不規范最終導致產品基礎包和開發包存在了相互引用。

針對當時我們的項目我考慮了兩種方案:

方案一、將產品基礎包和開發包整合成一個源碼包,再重構為Maven項目。

產品基礎包編譯成jar包,jsp頁面整合到開發包中。后續產品基礎包如果升級,重新編譯成jar包更換現有jar即可,涉及用到的jsp需要項目組開發團隊整合到正在使用的開發包中按正常版本發布流程提交源碼即可。(這種方案需人工整合為一個源碼包,相互間的引用自然就不存在了)

方案二、使用Maven聚合工程

使用Maven聚合工程,將產品基礎包和開發包分別構建成兩個Maven模塊,然后將開發包目前最新版本打成jar包放入Maven倉庫由產品基礎包引用從而斷掉產品基礎包對開發包之前的引用,之后開發時務必做到開發包單邊引用產品基礎包,便不會再出現產品基礎包對開發包的引用。剩下的就由開發包單邊依賴產品基礎包即可,從而可以避免循環依賴。后續產品基礎包如果升級,按正常版本發布流程提交源碼即可,無需人工整合,各自提交到各自的Maven模塊,無影響。(這種方案后期要確保:開發人員嚴格遵守開發規范開發包單邊引用產品基礎包)

考慮到一下兩種原因,最終采用了第二種方案:

1、整合兩個源碼包需要花費很長時間影響進度,且整合過程中也存在一定的風險。

2、后續產品基礎包可能存在升級

3、還有其他模塊功能待整合上線,需要考慮到可擴展性。

 

 

后面再網上查問題時碰到更好的方案,以下內容轉自:https://www.iteye.com/blog/hck-1728329l

很​多​時​候​隨​着​項​目​的​膨​脹​,模​塊​會​越​來​越​多​,如​果​設​計​上​ 稍​有​不​慎​就​會​出​現​模​塊​之​間​相​互​依​賴​的​情​況​。​這​對​於​使​用​Maven的​用​戶​是​比​較​痛​苦​的​,因​為​出​現​模​塊​之​間​相​互​依​賴​的​話​在​構​建​的​時​候​就​會​失​敗​,Maven通​常​要​先​編​譯​被​依​賴​的​模​塊​,如​果​出​現​相​互​依​賴​Maven就​不​知​道​該​怎​么​辦​了​。​下​圖​描​述​了​三​個​Maven模​塊​相​互​依​賴​的​場​景​: 

 

 

 圖​中​模​塊​C依​賴​於​模​塊​B,模​塊​B依​賴​於​模​塊​A,而​模​塊​A又​依​賴​於​模​塊​C,這​樣​就​出​現​了​相​互​依​賴​情​況​,如​果​運​行​mvn compile會​出​現​如​下​錯​誤​:
[INFO] Scanning for projects... [ERROR] The projects in the reactor contain a cyclic reference: Edge between 'Ve rtex{label='org.kuuyee.sample:module-C:1.0-SNAPSHOT'}' and 'Vertex{label='org.ku uyee.sample:module-B:1.0-SNAPSHOT'}' introduces to cycle in the graph org.kuuyee .sample:module-B:1.0-SNAPSHOT --> org.kuuyee.sample:module-A:1.0-SNAPSHOT --> or g.kuuyee.sample:module-C:1.0-SNAPSHOT --> org.kuuyee.sample:module-B:1.0-SNAPSHO T -> [Help 1][ERROR] [ERROR] To see the full stack trace of the errors, re-run Maven with the -e swit ch.[ERROR] Re-run Maven using the -X switch to enable full debug logging.[ERROR] [ERROR] For more information about the errors and possible solutions, please rea d the following articles: [ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/ProjectCycleEx ception
1. 使​用​build-helper-maven-plugin解​決​相​互​依​賴​的​問​題​我​的​解​決​辦​法​就​是​先​把​相​互​依​賴​的​模​塊​整​合​在​一​起​,相​當​於​把​這​些​模​塊​合​並​成​一​個​單​獨​的​模​塊​統​一​編​譯​,

這​樣​就​產​生​了​一​個​合​並​模​塊​D,我​們​把​它​當​做​一​個​輔​助​構​建​模​塊​,然​后​讓​A、​B、​C模​塊​都​依​賴​於​D模​塊​,這​樣​的​話​就​可​以​成​功​編​譯​A、​B和​C模​塊​,

 

 

 

 

 要​想​把​A、​B、​C三​個​模​塊​整​合​在​一​起​編​譯​,需​要​借​助​build-helper-maven-plugin插​件​,這​個​插​件​在​Maven構​建​周​期​提​供​一​些​輔​助​功​能​,下​面​列​出​插​件​的​提​供​的​功​能​列​表​: build-helper:add-source:添​加​更​多​的​構​建​源​碼​目​錄​ build-helper:add-test-source:添​加​更​多​的​測​試​源​碼​目​錄​ build-helper:add-resource:添​加​更​多​的​資​源​目​錄​ build-helper:add-test-resource:添​加​更​多​的​測​試​資​源​目​錄​ build-helper:attach-artifact:在​安​裝​和​部​署​周​期​附​加​artifacts build-helper:maven-version:添​加​一​個​指​定​當​前​Maven版​本​的​屬​性​ build-helper:parse-version:添​加​一​個​指​定​組​件​版​本​的​屬​性​ build-helper:released-version:決​定​當​前​項​目​的​最​終​版​本​ build-helper:remove-project-artifact:從​本​地​資​源​庫​中​移​除​項​目​的​artifacts build-helper:reserve-network-port:Reserve a list of random and unused network ports. 在​這​里​我​們​要​用​到​build-helper:add-source這​個​功​能​,將​模​塊​A、​B、​C的​源​碼​路​徑​加​進​來​。​ 我​們​再​添​加​一​個​輔​助​模​塊​D,在​輔​助​模​塊​D中​使​用​build-helper-maven-plugin插​件​,然​后​讓​模​塊​A、​B、​C都​依​賴​於​輔​助​模​塊​D,模​塊​D的​POM模​型​如​下​: 例 1. 輔​助​模​塊​D的​POM模​型​

java代碼:

  1. <project xmlns="http://maven.apache.org/POM/4.0.0"  
  2.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  3.     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">  
  4.     <parent>  
  5.         <groupId>org.kuuyee.sample</groupId>  
  6.         <artifactId>sample-parent</artifactId>  
  7.         <version>1.0-SNAPSHOT</version>  
  8.         <relativePath>../../pom.xml</relativePath>  
  9.     </parent>  
  10.     <modelVersion>4.0.0</modelVersion>  
  11.     <groupId>org.kuuyee.sample</groupId>  
  12.     <artifactId>module-D</artifactId>  
  13.     <version>1.0-SNAPSHOT</version>  
  14.     <packaging>jar</packaging>  
  15.     <name>module-D</name>  
  16.     <url>http://maven.apache.org</url>  
  17.     <properties>  
  18.         <project.build.sourceEncoding>  
  19.             UTF-8  
  20.         </project.build.sourceEncoding>  
  21.         <module.a.src>../../module/module-A/src/main/java</module.a.src>  
  22.         <module.b.src>../../module/module-B/src/main/java</module.b.src>  
  23.         <module.c.src>../../module/module-C/src/main/java</module.c.src>  
  24.     </properties>  
  25.     <build>  
  26.         <plugins><!-- 解決模塊相互依賴,綜合所有相互依賴代碼統一編譯 -->  
  27.             <plugin>  
  28.                 <groupId>org.codehaus.mojo</groupId>  
  29.                 <artifactId>build-helper-maven-plugin</artifactId>  
  30.                 <executions>  
  31.                     <execution>  
  32.                         <id>add-source</id>  
  33.                         <phase>generate-sources</phase>  
  34.                         <goals>  
  35.                             <goal>add-source</goal>  
  36.                         </goals>  
  37.                         <configuration>  
  38.                             <sources>  
  39.                                 <source>${module.a.src}</source>  
  40.                                 <source>${module.b.src}</source>  
  41.                                 <source>${module.c.src}</source>  
  42.                             </sources>  
  43.                         </configuration>  
  44.                     </execution>  
  45.                 </executions>  
  46.             </plugin>  
  47.         </plugins>  
  48.     </build>  
  49.     <dependencies>  
  50.         <dependency>  
  51.             <groupId>junit</groupId>  
  52.             <artifactId>junit</artifactId>  
  53.             <version>3.8.1</version>  
  54.             <scope>test</scope>  
  55.         </dependency>  
  56.     </dependencies>  
  57. </project>  

maven處理循環依賴

在多maven工程的項目里,如果工程間存在循環依賴,構建就會報錯。本文介紹一下循環依賴要怎么處理

1、什么是循環依賴

  如果工程A依賴工程B,工程B又依賴工程A,就會形成循環依賴。或者A依賴B,B依賴C,C依賴A,也是循環依賴
  
  總的來說,在畫出工程依賴圖之后,如果發現工程間的依賴連線形成了一個有向循環圖,則說明有循環依賴的現象
  
  如果循環依賴發生在工程之間,則會影響構建,因為maven不知道應該先編譯哪個工程。如果循環依賴發生在同一個工程的模塊之間,雖然不影響編譯,但是也是一種不好的實踐,說明模塊的設計有問題,應該避免
  
  如果在模塊內部,有幾個類互相調用的話,我覺得可能是正常的。比如觀察者模式里面,Observer和Observable就是互相依賴的

2、怎么解決循環依賴

  目前知道有2個辦法可以解決
  
  第一個辦法是用build-helper-maven-plugin插件來規避。比如A依賴B,B依賴C,C依賴A的情況。這個插件提供了一種規避措施,即臨時地將工程A、B、C合並成一個中間工程,編譯出臨時的模塊D。然后A、B、C再分別依賴臨時模塊D進行編譯
  
  這種方法可以解決無法構建的問題,但是只是一個規避措施,工程的依賴關系依然是混亂的
  
  第二個辦法是通過重構,從根本上消除循環依賴

3、如何重構

  目前也知道2個重構的思路
  
  第一個辦法是平移,比如A和B互相依賴,那么可以將B依賴A的那部分代碼,移動到工程B中,這樣一來,B就不需要繼續依賴A,只要A依賴B就可以了,從而消除循環依賴
  
  第二個辦法是下移,比如A和B互相依賴,同時它們都依賴C,那么可以將B和A相互依賴的那部分代碼,移動到工程C里,這樣一來,A和B相互之間都不依賴,只繼續依賴C,也可以消除循環依賴
  
  這兩種重構方式都是可行的,具體采用哪種方式要根據實際情況來判斷。不管采取哪種方式,都需要對代碼進行修改,有時候並不是那么容易的


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM