IntelliJ Idea14 創建Maven多模塊項目,多繼承,熱部署配置總結(二)

接著上文【IntelliJ Idea14 創建Maven多模塊項目,多繼承,熱部署配置總結(一)】,總結下項目熱部署和pom文件結構的一些要點:

一,依賴包的熱部署

上文中項目如果改了依賴包core模塊中的service服務代碼,重啟web服務是看不到改動效果的,這是因為依賴的core已經打成jar包給web模塊使用了,重啟并不會重新打jar包,所以只能重新package打包才能看到效果。
【解決方案】:把依賴的core模塊,編譯到web模塊里面去,在web下生成core的class文件,這樣重啟編譯就會實時更新界面了。
【未處理之前】:

在這里插入圖片描述

配置模塊的output layout下的class,選中對應的依賴右鍵,點擊put into output root
在這里插入圖片描述

【處理之后,重新打包,啟動】:
在這里插入圖片描述

有了class文件之后,重啟就能看到service的改動了。

此外Project Stucture里面還有一些其他要注意的點:
1,【Modules】當項目的JDK是1.8的時候,配置每個module的Language Level為對應的JDK的level;

2,【Facets】
檢查Facets右邊的【Deplyment Descriptors】,必須是指向web.xml
檢查Facets右邊的【Web Resource Directories】,必須是選中webapp的目錄,類似普通非maven的項目需要指向WebRoot或者WebContent目錄

3,【Artifacts】就是上面的熱部署配置。


二,pom配置要點

2.1 pom的繼承

1,項目模塊可以一層一層的繼承下去,比如多層級的module方式:

module-test
--- module-test-common
--- module-test-platform
--- --- module-test-platform-A
--- --- module-test-platform-B

由上可知:

  1. module-test-platform-A和module-test-platform-B的parent是module-test-platform
  2. module-test-platform和module-test-common的parent是module-test

上面配置要實現的話,也很簡單,只需要將module-test-platform的pom.xml里面配置成<packaging>pom</packaging>,然后module-test-platform-A和module-test-platform-B的parent都以來module-test-platform的GAV(maven三要素:groupId/artifactId/version)就行了。

<packaging>不寫的話默認是jar,意思就是打成jar包;
寫pom的意思就是做父模塊,給子模塊繼承或者引用;
寫war的意思就是打成war包給tomcat啟動;

在Maven 中除了用繼承parent來做版本控制以外, 還可以通過 scope=import 來做版本控制.

Maven 2.0.9 添加了一個新特性: scope = import 也就是從外部導入依賴管理的依賴配置. 使用過 DependencyManagement都知道, 多模塊構建項目的時候, 為了解決各模塊依賴版本一致, 統一在父pom.xml文件中統一定義各個依賴jar文件的版本, 然后子模塊通過引用的方式添加需要的依賴jar, 但隨著項目工程越來越大, 添加的依賴文件也越來也多, 父pom.xml的 DependencyManagement 也會越來越長, 不便于管理. 另外, 因為pom.xml 是單繼承的, 如果已經有一個父pom.xml了, 想要再引用外部的pom.xml, 就只能復制到父pom.xml中了. 因此采用在 DependencyManagement 中使用scope = import的方式可以分類引入更多的管理配置, 也擺脫了單繼承的限制.


使用import scope解決maven繼承(單)問題

想必大家在做SpringBoot應用的時候,都會有如下代碼:

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.3.3.RELEASE</version>
</parent>

繼承一個父模塊,然后再引入相應的依賴

假如說,我不想繼承,或者我想繼承多個,怎么做?

我們知道Maven的繼承和Java的繼承一樣,是無法實現多重繼承的,如果10個、20個甚至更多模塊繼承自同一個模塊,那么按照我們之前的做法,這個父模塊的dependencyManagement會包含大量的依賴。如果你想把這些依賴分類以更清晰的管理,那就不可能了,import scope依賴能解決這個問題。你可以把dependencyManagement放到單獨的專門用來管理依賴的pom中,然后在需要使用依賴的模塊中通過import scope依賴,就可以引入dependencyManagement。例如可以寫這樣一個用于依賴管理的pom:

<project>
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.test.sample</groupId>
    <artifactId>base-parent1</artifactId>
    <packaging>pom</packaging>
    <version>1.0.0-SNAPSHOT</version>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>junit</groupId>
                <artifactid>junit</artifactId>
                <version>4.8.2</version>
            </dependency>
            <dependency>
                <groupId>log4j</groupId>
                <artifactid>log4j</artifactId>
                <version>1.2.16</version>
            </dependency>
        </dependencies>
    </dependencyManagement>
</project>

然后我就可以通過非繼承的方式來引入這段依賴管理配置

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>com.test.sample</groupId>
            <artifactid>base-parent1</artifactId>
            <version>1.0.0-SNAPSHOT</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>
 
<dependency>
    <groupId>junit</groupId>
    <artifactid>junit</artifactId>
</dependency>
<dependency>
    <groupId>log4j</groupId>
    <artifactid>log4j</artifactId>
</dependency>

注意:import scope只能用在dependencyManagement里面

這樣,父模塊的pom就會非常干凈,由專門的packaging為pom來管理依賴,也契合的面向對象設計中的單一職責原則。此外,我們還能夠創建多個這樣的依賴管理pom,以更細化的方式管理依賴。這種做法與面向對象設計中使用組合而非繼承也有點相似的味道。

那么,如何用這個方法來解決SpringBoot的那個繼承問題呢?

配置如下:

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>1.3.3.RELEASE</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>
 
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
</dependencies>

這樣配置的話,自己的項目里面就不需要繼承SpringBoot的module了,而可以繼承自己項目的module了。

參考:https://blog.csdn.net/mn960mn/article/details/50894022


2.2 dependencies與dependencyManagement的區別

在我們項目頂層的POM文件中,我們會看到dependencyManagement元素。通過它元素來管理jar包的版本,讓子項目中引用一個依賴而不用顯示的列出版本號。Maven會沿著父子層次向上走,直到找到一個擁有dependencyManagement元素的項目,然后它就會使用在這個dependencyManagement元素中指定的版本號。

這樣做的好處:統一管理項目的版本號,確保應用的各個項目的依賴和版本一致,才能保證測試的和發布的是相同的成果,因此,在頂層pom中定義共同的依賴關系。同時可以避免在每個使用的子項目中都聲明一個版本號,這樣想升級或者切換到另一個版本時,只需要在父類容器里更新,不需要任何一個子項目的修改;如果某個子項目需要另外一個版本號時,只需要在dependencies中聲明一個版本號即可。子類就會使用子類聲明的版本號,不繼承于父類版本號。

區別:

dependencies即使在子項目中不寫該依賴項,那么子項目仍然會從父項目中繼承該依賴項(全部繼承)

dependencyManagement里只是聲明依賴,并不實現引入,因此子項目需要顯示的聲明需要用的依賴。如果不在子項目中聲明依賴,是不會從父項目中繼承下來的;只有在子項目中寫了該依賴項,并且沒有指定具體版本,才會從父項目中繼承該項,并且version和scope都讀取自父pom;另外如果子項目中指定了版本號,那么會使用子項目中指定的jar版本。


2.3 Maven依賴Scope選項詳解

在一個maven項目中,如果存在編譯需要而發布不需要的jar包,可以用scope標簽,值設為provided。

如下:

<dependency>
  <groupId>javax.servlet.jsp</groupId>
  <artifactId>jsp-api</artifactId>
  <version>2.3</version>
  <scope>provided</scope>      
</dependency>

Scope的其他參數如下:

compile:默認的scope,表示 dependency 都可以在生命周期中使用。
而且,這些dependencies 會傳遞到依賴的項目中。適用于所有階段,會隨著項目一起發布

provided:跟compile相似,但是表明了dependency 由JDK或者容器提供,例如Servlet AP和一些Java EE APIs。這個scope 只能作用在編譯和測試時,同時沒有傳遞性,即:child module無法引用。

runtime:表示dependency不作用在編譯時,但會作用在運行和測試時,如JDBC驅動,適用運行和測試階段,與provided相反。

test:表示dependency作用在測試時,不作用在運行時。 只在測試時使用,用于編譯和運行測試代碼。不會隨項目發布。

system:跟provided 相似,但是在系統中要以外部JAR包的形式提供,maven不會在repository查找它。


2.4 Maven的classifier作用

classifier可以是任意的字符串,用于拼接在GAV之后來確定指定的文件。
可用于區分不同jdk版本所生成的jar包

<dependency>  
    <groupId>net.sf.json-lib</groupId>   
    <artifactId>json-lib</artifactId>   
    <version>2.2.2</version>  
    <classifier>jdk15</classifier>    
</dependency>

<dependency>  
    <groupId>net.sf.json-lib</groupId>   
    <artifactId>json-lib</artifactId>   
    <version>2.2.2</version>  
    <classifier>jdk13</classifier>    
</dependency>

實際上對應的jar包是json-lib-2.2.2-jdk15.jarjson-lib-2.2.2-jdk13.jar

區分項目的不同組成部分,例如:源代碼、javadoc、類文件等。

<dependency>  
    <groupId>net.sf.json-lib</groupId>   
    <artifactId>json-lib</artifactId>   
    <version>2.2.2</version>  
    <classifier>jdk15-javadoc</classifier>    
</dependency> 

對應的是json-lib-2.2.2-jdk15-javadoc.jar

需要注意classifier的位置

<dependency>  
    <groupId>net.sf.json-lib</groupId>   
    <artifactId>json-lib</artifactId>   
    <classifier>jdk15-javadoc</classifier>  
    <version>2.2.2</version>   
</dependency> 

對應的是json-lib-jdk15-javadoc-2.2.2.jar。可能會出現找不到jar包的情況。

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容