簡體   English   中英

maven - 用於接口和Spring實現的獨立模塊

[英]maven - separate modules for interfaces and implementation with Spring

我們正在研究Mavenizing我們的java項目,我們希望在每個模塊的接口和實現之間建立一個清晰的分離。 為了做到這一點,我們希望將每個模塊分成兩個子模塊,一個用於它們使用的接口和數據對象,另一個用於實現。 例如:

 +commons 
  +commons-api 
  +commons-impl 

將配置模塊的POM,使得沒有模塊依賴於impl子模塊。 這樣,來自一個模塊的代碼就無法“看到”另一個模塊的實現細節。

我們遇到麻煩的是,將Spring XML放在哪里。 在我們的項目中,我們使用通配符導入自動導入spring XML文件

<import resource="classpath*:**/*-beans.xml"/>

這樣,Spring XML的位置在運行時並不重要,因為所有模塊都被加載到同一個類加載器中,並且POM中嚴格的單向依賴規則不適用。

但是,在開發過程中,我們希望IDE(我們使用Intellij IDEA)識別從spring XML引用的實現類。 我們還希望IDEA識別其他模塊中定義的bean。

如果我們將spring XML放在API子模塊中 - 它們將不會“看到”impl子模塊中的實現類。 如果我們將它們放在impl子模塊中,它們的bean將不會從其他模塊中“看到”。 可能可以將IDEA項目配置為從沒有依賴項的模塊中識別spring XML,但我們更喜歡POM保存所有項目結構信息而不依賴於IDEA項目文件。

我們考慮創建第三個子模塊只是為了保存Spring XML(也許還有hibernate xmls)。 例如:

 +commons 
  +commons-api 
  +commons-impl 
  +commons-config

外部模塊將依賴於commons-apicommons-configcommons-config將依賴於commons-apicommons-impl ,並且依賴於commons-impl標記為“提供”(以防止傳遞解析)。

然而,這似乎是一個復雜而笨拙的解決方案,我們認為必須有一個更好 - 更簡單的方法來實現與Maven和Spring的接口/ impl分離。

您需要的是運行時依賴范圍:

runtime - 此范圍指示編譯不需要依賴項,但是用於執行。 它位於運行時和測試類路徑中,但不是編譯類路徑。

https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html

定義從一個impl模塊到另一個impl模塊的運行時依賴關系,您可以在其中使用* -beans.xml配置中的impl類。 Intellij會在spring配置文件中正確識別它,但不會在代碼中自動完成它們(但它會在測試代碼中完成)。

此外,如果有人在代碼中使用這些類,則通過maven進行編譯會失敗,因為運行時依賴性不在編譯類路徑上。

你可以像這樣實現api和impl的解耦:

+ commons (pom)
  + pom.xml         <--- serves as a parent aggregator (see below)
  + commons-api (jar)  <--- contains models, interfaces and abstract classes only
  + commons-impl (jar)  <--- depends on commons-api
  + commons-config (jar) <--- depends on commons-impl only (no need to depend on commons-api as it is brought in transitively)

 + external-project (war or jar) <--- has commons-config as a dependency

父聚合器pom(指定構建順序):

<modules>
  <module>commons-api</module>
  <module>commons-impl</module>
  <module>commons-config</module>
</modules>

如果配置模塊僅包含spring應用程序上下文配置,則可以省略它。 應用程序配置xml應位於包含要部署的工件的模塊的類路徑和文件夾結構中。 因此,如果您正在構建戰爭工件,應用程序上下文應該在那里。

應該在commons模塊中的唯一配置是在impl模塊的測試包中。

簡而言之,您希望Idea覆蓋maven依賴關系圖,但避免將此配置保留在想法項目文件中?

一種選擇是在maven配置文件中對實現依賴性進行分組。 默認情況下不會啟用此配置文件,但您應該能夠在想法下將其標記為活動狀態。

想到兩個想法:

  1. 您將擁有一個(或多個)模塊,其中所有模塊(api + impl)都是依賴項,您可以將彈簧配置文件放在那里。
  2. 將彈簧配置文件在API模塊和聲明與范圍IMPL模塊的依賴關系provided這樣的實施方式將是已知的,而沒有該API為部署的依賴性。
  • commons-impl在外部模塊的運行時范圍內

    1. 公共(pom dependencyManagement)=>

      + commons-api(編譯)

      + commons-impl(編譯)

      + commons-config(編譯)

    2. commons-impl(pom dependencies)=>

      + commons-api(編譯)

      + commons-config(編譯)

    3. 外部模塊(pom依賴)=>

      + commons-impl( 運行時

      + commons-api(編譯)

      + commons-config(編譯)

  1. 保持模塊數量盡可能少;

    這加快了項目構建時間並簡化了布局。

  2. 保持模塊結構盡可能簡單:單根+同一文件夾中的所有子模塊,例如:

     pom.xml commons-api/ commons-runtime/ module-a-api/ module-a-runtime/ ... 

當模塊數量非常高(> 50)時,這簡化了項目的導航

  1. 僅在需要時為運行時模塊提供運行時范圍的依賴關系;

    這可以保持您的架構清晰。 使用mocks而不是顯式依賴於另一個運行時模塊。

  2. 在api模塊中保存api spring上下文,將公共bean定義為abstract bean + interface;

  3. 將您的實現上下文保留在運行時模塊中,通過spring配置文件覆蓋api bean(使用<beans profile =“default”)。

結果:簡單,透明的布局和設計; 全力支持; 沒有對運行時模塊內部的顯式依賴。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM