Maven學習(三) - 聚合與繼承

在實際項目的使用中,經常會對項目進行模塊劃分,以下降耦合。如服務接口模塊,各業務模塊,web模塊等。而模塊間共享一些相同的依賴,彼此間也緊密聯繫。此時咱們就能夠經過maven的聚合繼承來管理模塊。java

好比如今咱們有如下模塊:web

  1. example-api
  2. example-service
  3. example-web

模塊間的關係是example-web和example-service經過example-api相鏈接。spring

example-web -> example-api <- example-service

此時咱們能夠建立一個聚合模塊example-parent,也能夠稱做父模塊。它的pom.xml以下apache

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">  
  <modelVersion>4.0.0</modelVersion>  
  
  <groupId>com.lcifn.maven</groupId>  
  <artifactId>example-parent</artifactId>  
  <version>0.0.1</version>  
  <packaging>pom</packaging>  
  
  <name>example</name>
  
  <modules>
		<module>example-api</module>
		<module>example-service</module>
		<module>example-web</module>
	</modules>
  
</project>

對於聚合模塊來講,其打包方式packaging的值必須爲pom,不然沒法構建。通常聚合模塊的內容僅是一個pom.xml,它就是幫助聚合其餘模塊構建的工具。api

而對於子模塊來講,經過繼承父pom,將公共的配置統一在父pom中管理,好比依賴的版本以及插件的管理。maven

以example-api爲例工具

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">  
  <modelVersion>4.0.0</modelVersion>  
  
    <parent>
        <groupId>com.lcifn.maven</groupId>
        <artifactId>example-parent</artifactId>
        <version>0.0.1</version>
    </parent>
    
    <artifactId>example-api</artifactId>  
    <version>0.0.1</version> 
    
</project>

parent標籤內的子元素groupId,artifactId和version指定父模塊的座標。對於子模塊,父模塊的pom中不少元素是能夠繼承的ui

  • groupId
  • version
  • distributionManagement 項目部署配置
  • properties 自定義maven屬性
  • dependencies 項目依賴配置
  • dependencyManagement 項目依賴管理配置
  • repositories 項目的倉庫配置
  • build 包括項目源碼目錄配置,輸出目錄配置,插件配置,插件管理配置

以上只是列舉了經常使用的一些元素插件

實際使用時,聚合模塊和父模塊每每是同一模塊code

依賴管理

項目中依賴的spring多個組件但願都是同一版本的,這樣能避免因版本問題出現的奇怪錯誤,能夠經過maven的dependencyManagement來管理。在dependencyManagement元素下的依賴聲明不會引入實際的依賴,而它能夠約束dependencies下的依賴的使用。

在父模塊的pom中加入配置

<properties>
    <spring.version>4.1.6.RELEASE</spring.version>
</properties>

<dependencyManagement>
	<dependencies>
    	<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-jdbc</artifactId>
			<version>${spring.version}</version>
		</dependency>
	</dependencies>
</dependencyManagement>

將經常使用的依賴版本以maven變量提取出來,消除重複,並方便之後升級。

在子模塊的pom文件中,只須要配置groupId和artifactId就能得到對應的依賴信息,從而可讓多個模塊統一使用統一版本的依賴,減小依賴衝突。

<dependencies>
	<dependency>
	    <groupId>org.springframework</groupId>
		<artifactId>spring-context</artifactId>
	</dependency>
	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-jdbc</artifactId>
	</dependency>
</dependencies>

插件管理

maven也提供了pluginManagement元素幫助管理插件,在該元素中配置的依賴不會形成實際的插件調用行爲,當子模塊的pom中配置了真正的plugin元素,而且groupId和artifactId與pluginManagement中配置的插件匹配時,pluginManagement的配置纔會產生真正的影響。

父模塊的pom文件,配置maven-source-plugin,將jar-no-fork目標綁定到verify生命週期階段,生成項目源碼包。

<pluginManagement>
	<plugins>
		<plugin>
			<groupId>org.apache.maven.plugins</groupId>
			<artifactId>maven-source-plugin</artifactId>
			<version>3.0.1</version>
			<executions>
				<execution>
					<id>attach-sources</id>
					<phase>verify</phase>
					<goals>
						<goal>jar-no-fork</goal>
					</goals>
				</execution>
			</executions>
		</plugin>
	</plugins>
</pluginManagement>

當子模塊須要生成源碼包時,只須要簡單配置

<plugins>
	<plugin>
		<groupId>org.apache.maven.plugins</groupId>
		<artifactId>maven-source-plugin</artifactId>
	</plugin>
</plugins>

約定優於配置

maven提倡「約定優於配置」,從而能夠減小大量的配置。一個項目構建要完成的最基本的事情,包括清除構建目錄,建立目錄,編譯代碼,複製依賴至目標目錄,最後打包。若是使用ant,須要在配置文件中指定源碼目錄是什麼,編譯目標目錄是什麼,分發目錄是什麼等等。而使用maven後,用戶付出必定的代價來遵照manven的約定,便可用很是簡單的pom文件來達到相同的目的。

maven對用戶目錄的約定以下

  • 源碼目錄爲src/main/java/
  • 編譯輸出目錄爲target/classes/
  • 打包方式爲jar
  • 包輸出目錄爲target/

這些默認的約定定義在maven的超級pom文件中,任何一個Maven項目都隱式繼承該pom,有點相似jave類都繼承於Object類。對於maven3,超級pom文件在$MAVEN_HOME$/lib/maven-model-builder-3.3.1.jar中的org\apache\maven\model\pom-4.0.0.xml。

簡單列舉下超級pom中對項目結構的定義

<build>
    <directory>${project.basedir}/target</directory>
    <outputDirectory>${project.build.directory}/classes</outputDirectory>
    <finalName>${project.artifactId}-${project.version}</finalName>
    <testOutputDirectory>${project.build.directory}/test-classes</testOutputDirectory>
    <sourceDirectory>${project.basedir}/src/main/java</sourceDirectory>
    <scriptSourceDirectory>${project.basedir}/src/main/scripts</scriptSourceDirectory>
    <testSourceDirectory>${project.basedir}/src/test/java</testSourceDirectory>
    <resources>
      <resource>
        <directory>${project.basedir}/src/main/resources</directory>
      </resource>
    </resources>
    <testResources>
      <testResource>
        <directory>${project.basedir}/src/test/resources</directory>
      </testResource>
    </testResources>
</build>

反應堆

在一個多模塊的Maven項目中,反應堆(Reactor)指全部模塊組成的一個構建結構。對於單模塊的項目,反應堆就是模塊自身,而對於多模塊項目,反應堆就包含了各模塊之間繼承與依賴的關係,從而可以自動計算合理的模塊構建順序。

上述example-parent的構建順序就是

  1. example-parent
  2. example-api
  3. example-service
  4. example-web

模塊間的依賴關係會將反應堆構成一個有向非循環圖。當出現兩個模塊相互依賴時,maven會報錯。

有些時候,用戶會想僅僅構建完整反應堆的某些個模塊,即裁剪反應堆。maven提供命令支持裁剪反應堆。

  • -am,--also-make 同時構建所列模塊的依賴模塊
  • -amd,-alos-make-dependents 同時構建依賴於所列模塊的模塊
  • -pl,--projects 構建指定的模塊,模塊間用逗號隔開
  • -rf,--resume-from 從指定的模塊恢復反應堆

可使用-pl指定構建某幾個模塊

mvn clean install -pl example-api,example-service

使用-am同時構建所列模塊的依賴模塊

mvn clean install -pl example-service -am

使用-amd構建依賴於所列模塊的模塊

mvn clean install -pl example-api -amd

使用-rf在完整反應堆構建順序基礎上指定從哪一個模塊開始構建

mvn clean install -rf example-service

在開發過程當中,靈活應用上述參數,能夠幫助咱們跳過無須構建的模塊,從而加速構建,尤爲在項目龐大,模塊衆多的時候。

相關文章
相關標籤/搜索