maven的pom文件與打包詳解
setting.xml 是全局級(jí)別的配置文件
,主要用于配置 maven 的運(yùn)行環(huán)境等一系列通用的屬性。
pom.xml 是項(xiàng)目級(jí)別的配置文件
。 pom 作為項(xiàng)目對(duì)象模型。通過(guò) xml 表示 maven 項(xiàng)目,使用 pom.xml 來(lái)實(shí)現(xiàn)。主要描述了:項(xiàng)目的 maven 坐標(biāo)、依賴關(guān)系、開(kāi)發(fā)者需要遵循的規(guī)則、缺陷管理系統(tǒng)、組織和 licenses、項(xiàng)目的 url、項(xiàng)目的依賴性,以及其他所有的項(xiàng)目相關(guān)因素。
一、基礎(chǔ)配置
<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.0http://maven.apache.org/xsd/maven-4.0.0.xsd"> <!-- 模型版本。maven2.0必須是這樣寫(xiě),現(xiàn)在是maven2唯一支持的版本 --> <modelVersion>4.0.0</modelVersion> <!-- 公司或者組織的唯一標(biāo)志,并且配置時(shí)生成的路徑也是由此生成, 如 cn.edu.ouc,maven 會(huì)將該項(xiàng)目打成的 jar 包放本地路徑:/cn/edu/ouc --> <groupId>cn.edu.ouc</groupId> <!-- 本項(xiàng)目的唯一ID,一個(gè)groupId下面可能多個(gè)項(xiàng)目,就是靠artifactId來(lái)區(qū)分的 --> <artifactId>pom-learning</artifactId> <!-- 本項(xiàng)目目前所處的版本號(hào) --> <version>1.0.0-SNAPSHOT</version> <!-- 打包的機(jī)制,如 pom、jar、maven-plugin、ejb、war、ear、rar和par,默認(rèn)為jar --> <packaging>jar</packaging> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.4.3</version> </parent> <!-- 幫助定義構(gòu)件輸出的一些附屬構(gòu)件,附屬構(gòu)件與主構(gòu)件對(duì)應(yīng),有時(shí)候需要加上classifier才能唯一的確定該構(gòu)件 不能直接定義項(xiàng)目的classifer,因?yàn)楦綄贅?gòu)件不是項(xiàng)目直接默認(rèn)生成的,而是由附加的插件幫助生成的 --> <classifier>...</classifier> <!-- 為 pom 定義一些常量,在 pom 中的其它地方可以直接引用這些變量。使用方式如下:${file.encoding} --> <properties> <file.encoding>UTF-8</file.encoding> <java.source.version>1.5</java.source.version> <java.target.version>1.5</java.target.version> </properties> <!-- 定義本項(xiàng)目的依賴關(guān)系 --> <dependencies> <!-- 每個(gè)dependency都對(duì)應(yīng)這一個(gè)jar包 --> <dependency> <!--一般情況下,maven是通過(guò)groupId、artifactId、version這三個(gè)元素值(俗稱(chēng)坐標(biāo))來(lái)檢索該構(gòu)件, 然后引入你的工程。如果別人想引用你現(xiàn)在開(kāi)發(fā)的這個(gè)項(xiàng)目(前提是已開(kāi)發(fā)完畢并發(fā)布到了遠(yuǎn)程倉(cāng)庫(kù)),--> <!--就需要在他的pom文件中新建一個(gè)dependency節(jié)點(diǎn),將本項(xiàng)目的groupId、artifactId、version寫(xiě)入, maven就會(huì)把你上傳的jar包下載到他的本地 --> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.1.5.RELEASE</version> <!-- maven認(rèn)為,程序?qū)ν獠康囊蕾嚂?huì)隨著程序的所處階段和應(yīng)用場(chǎng)景而變化,所以maven中的依賴關(guān)系有作用域(scope)的限制。 --> <!--scope包含如下的取值:compile(編譯范圍)、provided(已提供范圍)、runtime(運(yùn)行時(shí)范圍)、test(測(cè)試范圍)、system(系統(tǒng)范圍) --> <scope>test</scope> <!-- 設(shè)置子項(xiàng)目是否默認(rèn)繼承該依賴:默認(rèn)為 false,即子項(xiàng)目默認(rèn)都繼承,子項(xiàng)目不需要顯示的引入;若為 true 則子項(xiàng)目必需顯示的引入,與dependencyManagement里定義的依賴類(lèi)似 --> <optional>false</optional> <!-- 屏蔽依賴關(guān)系,使其不起作用。比如項(xiàng)目中使用的libA依賴某個(gè)庫(kù)的1.0版,libB依賴某個(gè)庫(kù)的2.0版,現(xiàn)在想統(tǒng)一使用2.0版,就應(yīng)該屏蔽掉對(duì)1.0版的依賴 --> <exclusions> <exclusion> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> </exclusion> </exclusions> </dependency> </dependencies> ... </project>
一般來(lái)說(shuō),上面的幾個(gè)配置項(xiàng)對(duì)任何項(xiàng)目都是必不可少的,定義了項(xiàng)目的基本屬性。
1、<parent> 標(biāo)簽
< parent> 用于引用父工程,統(tǒng)一管理默認(rèn)配置以及 jar 包的版本,其依賴需要在子工程中定義才有效。
1)使用 spring-boot-starter-parent
spring-boot-starter-parent 是一個(gè)特殊的 starter,它用來(lái)提供相關(guān)的 Maven 默認(rèn)依賴:定義 Java 編譯版本為 1.8 ;項(xiàng)目使用 UTF-8 編碼
;繼承自 spring-boot-dependencies,這個(gè)里邊定義了依賴的版本,也正是因?yàn)槔^承了這個(gè)依賴,所以我們?cè)趯?xiě)依賴時(shí)才不需要寫(xiě)版本號(hào);執(zhí)行打包操作的配置;自動(dòng)化的資源過(guò)濾;自動(dòng)化的插件配置;針對(duì) application.properties 和 application.yml 的資源過(guò)濾,包括通過(guò) profile 定義的不同環(huán)境的配置文件。
2)使用自定義 parent
但是并非所有的公司都需要這個(gè) parent,有的時(shí)候,公司會(huì)自定義 parent,我們的 SpringBoot 項(xiàng)目只能繼承一個(gè) parent,繼承了公司內(nèi)部的 parent 就不能再繼承這個(gè)了,這個(gè)時(shí)候怎么辦呢?
對(duì)于依賴版本,我們可以定義 <dependencyManagement> 節(jié)點(diǎn),然后在里面定義好版本號(hào),接下來(lái)引用依賴時(shí)也就不用寫(xiě)版本號(hào)
了,像下面這樣:
<dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.3.1.RELEASE</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
這樣寫(xiě)之后,就可以不用繼承spring-boot-starter-parent了,但依賴的版本號(hào)問(wèn)題雖然解決了,但是關(guān)于打包的插件、編譯的JDK版本、文件的編碼格式等等這些配置,在沒(méi)有parent的時(shí)候,這些統(tǒng)統(tǒng)要自己去配置。
Java版本的配置很簡(jiǎn)單,添加一個(gè)plugin即可:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.1</version> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin>
編碼格式,在pom.xml中加入如下配置:
<properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> </properties>
2、classifier 元素
這里有必要對(duì)一個(gè)不太常用的屬性 classifier 做一下解釋?zhuān)驗(yàn)橛袝r(shí)候引用某個(gè) jar 包,classifier 不寫(xiě)的話會(huì)報(bào)錯(cuò)。
classifier 元素用來(lái)幫助定義構(gòu)件輸出的一些附屬構(gòu)件
。附屬構(gòu)件與主構(gòu)件對(duì)應(yīng),比如主構(gòu)件是 kimi-app-2.0.0.jar,該項(xiàng)目可能還會(huì)通過(guò)使用一些插件生成,如 kimi-app-2.0.0-javadoc.jar (Java文檔)、kimi-app-2.0.0-sources.jar(Java源代碼)這樣兩個(gè)附屬構(gòu)件。這時(shí)候javadoc、sources 就是這兩個(gè)附屬構(gòu)件的 classifier,這樣附屬構(gòu)件也就擁有了自己唯一的坐標(biāo)。
3、classifier 的用途:
1)maven download javadoc / sources jar 包的時(shí)候,需要借助 classifier 指明要下載那個(gè)附屬構(gòu)件
2)引入依賴的時(shí)候,有時(shí)候僅憑 groupId、artifactId、version 無(wú)法唯一的確定某個(gè)構(gòu)件,需要借助 classifier 來(lái)進(jìn)一步明確目標(biāo)。比如 JSON-lib,有時(shí)候會(huì)同一個(gè)版本會(huì)提供多個(gè)jar包,在 JDK1.5 環(huán)境下是一套,在 JDK1.3 環(huán)境下是一套:
引用它的時(shí)候就要注明 JDK 版本,否則 maven 不知道你到底需要哪一套jar包:
<dependency> <groupId>net.sf.json-lib</groupId> <artifactId>json-lib</artifactId> <version>2.4</version> <classifier>jdk15</classifier> </dependency>
二、構(gòu)建配置
<build> <!-- 產(chǎn)生的構(gòu)建的文件名,默認(rèn)值是 ${artifactId}-${version} --> <finalName>myPorjectName</finalName> <!-- 構(gòu)建產(chǎn)生的所有文件存放的目錄,默認(rèn)為 ${basedir}/target,即項(xiàng)目根目錄下的 target --> <directory>${basedir}/target</directory> <!--當(dāng)項(xiàng)目沒(méi)有規(guī)定目標(biāo)(Maven2叫做階段(phase))時(shí)的默認(rèn)值 --> <!--必須跟命令行上的參數(shù)相同例如jar:jar,或者與某個(gè)階段(phase)相同例如install、compile等 --> <defaultGoal>install</defaultGoal> <!--當(dāng) filtering 開(kāi)關(guān)打開(kāi)時(shí),使用到的過(guò)濾器屬性文件列表。 --> <!--項(xiàng)目配置信息中諸如 ${spring.version} 之類(lèi)的占位符會(huì)被屬性文件中的實(shí)際值替換掉 --> <filters> <filter>../filter.properties</filter> </filters> <!--項(xiàng)目相關(guān)的所有資源路徑列表,例如和項(xiàng)目相關(guān)的配置文件、屬性文件,這些資源被包含在最終的打包文件里。 --> <resources> <resource> <!--描述了資源的目標(biāo)路徑。該路徑相對(duì)target/classes目錄(例如${project.build.outputDirectory})。 --> <!--舉個(gè)例子,如果你想資源在特定的包里(org.apache.maven.messages),你就必須該元素設(shè)置為org/apache/maven/messages。 --> <!--然而,如果你只是想把資源放到源碼目錄結(jié)構(gòu)里,就不需要該配置。 --> <targetPath>resources</targetPath> <!--是否使用參數(shù)值代替參數(shù)名。參數(shù)值取自properties元素或者文件里配置的屬性,文件在filters元素里列出。 --> <filtering>true</filtering> <!--描述存放資源的目錄,該路徑相對(duì)POM路徑 --> <directory>src/main/resources</directory> <!--要被打包的資源列表 --> <includes> <include>**/*.properties</include> <include>**/*.xml</include> </includes> <!--排除的資源列表,這些資源不會(huì)被打包。如果<include>與<exclude>劃定的范圍存在沖突,以<exclude>為準(zhǔn) --> <excludes> <exclude>jdbc.properties</exclude> </excludes> </resource> </resources> <!--單元測(cè)試需要用到的的所有資源路徑,配置方法與resources類(lèi)似 --> <testResources> <testResource> <targetPath /> <filtering /> <directory /> <includes /> <excludes /> </testResource> </testResources> <!--項(xiàng)目源碼目錄,當(dāng)構(gòu)建項(xiàng)目的時(shí)候,構(gòu)建系統(tǒng)會(huì)編譯目錄里的源碼。該路徑是相對(duì)于pom.xml的相對(duì)路徑。 --> <sourceDirectory>${basedir}\src\main\java</sourceDirectory> <!--項(xiàng)目腳本源碼目錄,該目錄和源碼目錄不同,絕大多數(shù)情況下,該目錄下的內(nèi)容會(huì)被拷貝到輸出目錄(因?yàn)槟_本是被解釋的,而不是被編譯的)。 --> <scriptSourceDirectory>${basedir}\src\main\scripts </scriptSourceDirectory> <!--項(xiàng)目單元測(cè)試使用的源碼目錄,當(dāng)測(cè)試項(xiàng)目的時(shí)候,構(gòu)建系統(tǒng)會(huì)編譯目錄里的源碼。該路徑是相對(duì)于pom.xml的相對(duì)路徑。 --> <testSourceDirectory>${basedir}\src\test\java</testSourceDirectory> <!--被編譯過(guò)的應(yīng)用程序class文件存放的目錄。 --> <outputDirectory>${basedir}\target\classes</outputDirectory> <!--被編譯過(guò)的測(cè)試class文件存放的目錄。 --> <testOutputDirectory>${basedir}\target\test-classes</testOutputDirectory> <!--項(xiàng)目的一系列構(gòu)建擴(kuò)展,它們是一系列build過(guò)程中要使用的產(chǎn)品,會(huì)包含在running bulid's classpath里面。 --> <!--他們可以開(kāi)啟extensions,也可以通過(guò)提供條件來(lái)激活plugins。 --> <!--簡(jiǎn)單來(lái)講,extensions是在build過(guò)程被激活的產(chǎn)品 --> <extensions> <!--例如,通常情況下,程序開(kāi)發(fā)完成后部署到線上Linux服務(wù)器,可能需要經(jīng)歷打包、將包文件傳到服務(wù)器、SSH連上服務(wù)器、敲命令啟動(dòng)程序等一系列繁瑣的步驟。 --> <!--實(shí)際上這些步驟都可以通過(guò)Maven的一個(gè)插件 wagon-maven-plugin 來(lái)自動(dòng)完成 --> <!--下面的擴(kuò)展插件wagon-ssh用于通過(guò)SSH的方式連接遠(yuǎn)程服務(wù)器, --> <!--類(lèi)似的還有支持ftp方式的wagon-ftp插件 --> <extension> <groupId>org.apache.maven.wagon</groupId> <artifactId>wagon-ssh</artifactId> <version>2.8</version> </extension> </extensions> <!--使用的插件列表 。 --> <plugins> <plugin> <groupId></groupId> <artifactId>maven-assembly-plugin</artifactId> <version>2.5.5</version> <!--在構(gòu)建生命周期中執(zhí)行一組目標(biāo)的配置。每個(gè)目標(biāo)可能有不同的配置。 --> <executions> <execution> <!--執(zhí)行目標(biāo)的標(biāo)識(shí)符,用于標(biāo)識(shí)構(gòu)建過(guò)程中的目標(biāo),或者匹配繼承過(guò)程中需要合并的執(zhí)行目標(biāo) --> <id>assembly</id> <!--綁定了目標(biāo)的構(gòu)建生命周期階段,如果省略,目標(biāo)會(huì)被綁定到源數(shù)據(jù)里配置的默認(rèn)階段 --> <phase>package</phase> <!--配置的執(zhí)行目標(biāo) --> <goals> <goal>single</goal> </goals> <!--配置是否被傳播到子POM --> <inherited>false</inherited> </execution> </executions> <!--作為DOM對(duì)象的配置,配置項(xiàng)因插件而異 --> <configuration> <finalName>${finalName}</finalName> <appendAssemblyId>false</appendAssemblyId> <descriptor>assembly.xml</descriptor> </configuration> <!--是否從該插件下載Maven擴(kuò)展(例如打包和類(lèi)型處理器), --> <!--由于性能原因,只有在真需要下載時(shí),該元素才被設(shè)置成true。 --> <extensions>false</extensions> <!--項(xiàng)目引入插件所需要的額外依賴 --> <dependencies> <dependency>...</dependency> </dependencies> <!--任何配置是否被傳播到子項(xiàng)目 --> <inherited>true</inherited> </plugin> </plugins> <!--主要定義插件的共同元素、擴(kuò)展元素集合,類(lèi)似于dependencyManagement, --> <!--所有繼承于此項(xiàng)目的子項(xiàng)目都能使用。該插件配置項(xiàng)直到被引用時(shí)才會(huì)被解析或綁定到生命周期。 --> <!--給定插件的任何本地配置都會(huì)覆蓋這里的配置 --> <pluginManagement> <plugins>...</plugins> </pluginManagement> </build>
Maven 是通過(guò) pom.xml 來(lái)執(zhí)行任務(wù)的,其中的 <build> 標(biāo)簽描述了如何來(lái)編譯及打包項(xiàng)目,而具體的編譯和打包工作是通過(guò) build 中配置的 plugin 來(lái)完成
。當(dāng)然plugin配置不是必須的,默認(rèn)情況下,Maven 會(huì)綁定以下幾個(gè)插件來(lái)完成基本操作。
在 Maven的pom.xml 文件中,存在如下兩種 <build>:
全局配置(project build):是<project>的直接子元素,針對(duì)整個(gè)項(xiàng)目的所有情況都有效;
局部配置(profile build):是<profile>的直接子元素,針對(duì)不同的profile配置。
字段說(shuō)明
1、finalName:build目標(biāo)文件的名稱(chēng),默認(rèn)情況為 ${artifactId}-${version}。
2、defaultGoal:執(zhí)行 build 任務(wù)時(shí),如果沒(méi)有指定目標(biāo),將使用的默認(rèn)值。如上配置,在命令行中執(zhí)行 mvn,則相當(dāng)于執(zhí)行 mvn install。
3、directory:build 結(jié)果文件的存放目錄,默認(rèn)在 ${basedir}/target 目錄。
4、filter:定義 *.properties 文件,包含一個(gè) properties 列表,該列表會(huì)應(yīng)用到支持 filter 的 resources 中。也就是說(shuō),定義在 filter 的文件中的 name=value 鍵值對(duì),會(huì)在 build 時(shí)代替 ${name}
值應(yīng)用到 resources 中。maven 的默認(rèn) filter 文件夾為 ${basedir}/src/main/filters。
5、resources: 一個(gè) resource 元素的列表。每一個(gè)都描述與項(xiàng)目關(guān)聯(lián)的文件是什么和在哪里。
6、testResources: 定義和resource類(lèi)似,只不過(guò)在test時(shí)使用。
7、Project Build 特有的 <…Directory>:往往配置在父項(xiàng)目中,供所有父子項(xiàng)目使用。
8、Project Build 特有的 <extensions>:<extensions> 是執(zhí)行構(gòu)建過(guò)程中可能用到的其他工具,在執(zhí)行構(gòu)建的過(guò)程中被加入到 classpath 中
。也可以通過(guò) <extensions>**構(gòu)建插件,從而改變構(gòu)建的過(guò)程。通常,通過(guò) <extensions> 給出通用插件的一個(gè)具體實(shí)現(xiàn),用于構(gòu)建過(guò)程。
9、plugins:<plugins> 給出構(gòu)建過(guò)程中所用到的插件。
- groupId
- artifactId
- version
- extensions:是否加載該插件的擴(kuò)展,默認(rèn)false;
- inherited:該插件的 configuration 中的配置是否可以被(繼承該P(yáng)OM的其他Maven項(xiàng)目)繼承,默認(rèn)true;
- configuration:該插件所需要的特殊配置,在父子項(xiàng)目之間可以覆蓋或合并;
- dependencies:該插件所特有的依賴類(lèi)庫(kù);
- executions:該插件的某個(gè)goal(一個(gè)插件中可能包含多個(gè)goal)的執(zhí)行方式。一個(gè)execution有如下設(shè)置:
- id:唯一標(biāo)識(shí);
- goals:要執(zhí)行的插件的goal(可以有多個(gè)),如<goal>run</goal>;
- phase:插件的goal要嵌入到Maven的phase中執(zhí)行,如verify;
- inherited:該execution是否可被子項(xiàng)目繼承;
- configuration:該execution的其他配置參數(shù);
10、<pluginManagement> :在 <build> 中,<pluginManagement> 與 <plugins> 并列,兩者之間的關(guān)系類(lèi)似于 <dependencyManagement> 與 <dependencies> 之間的關(guān)系。<pluginManagement> 中也配置 <plugin>,其配置參數(shù)與 <plugins> 中的 <plugin>完全一致。<pluginManagement> 往往出現(xiàn)在父項(xiàng)目中,其中配置的 <plugin>往往通用于子項(xiàng)目。子項(xiàng)目中只要在 <plugins> 中以 <plugin> 聲明該插件,該插件的具體配置參數(shù)則繼承自父項(xiàng)目中 <pluginManagement> 對(duì)該插件的配置,從而避免在子項(xiàng)目中進(jìn)行重復(fù)配置
。
三、profile 配置
有些時(shí)候,一個(gè)項(xiàng)目需要適配多種開(kāi)發(fā)環(huán)境,如數(shù)據(jù)庫(kù)不同(mysql、oracle、db2等)、如開(kāi)發(fā)環(huán)境不同(dev、pro、test)等不同的環(huán)境需要指定不同的配置。這種情況下,我們就可以采用配置 profiles 來(lái)控制。在啟動(dòng)的時(shí)候指定不同的配置組合,maven進(jìn)行build時(shí)會(huì)自動(dòng)選擇指定配置。
<!-- 定義配置文件 --> <profiles> <!-- 配置文件 id 名字 properties 參數(shù) --> <profile> <id>dev</id> <!--自動(dòng)觸發(fā)profile的條件邏輯。Activation是profile的開(kāi)啟鑰匙。 --> <activation> <!--profile默認(rèn)是否激活的標(biāo)識(shí) --> <activeByDefault>true</activeByDefault> <!--activation有一個(gè)內(nèi)建的java版本檢測(cè),如果檢測(cè)到j(luò)dk版本與期待的一樣,profile被激活。 --> <jdk>1.7</jdk> <!--當(dāng)匹配的操作系統(tǒng)屬性被檢測(cè)到,profile被激活。os元素可以定義一些操作系統(tǒng)相關(guān)的屬性。 --> <os> <!--激活profile的操作系統(tǒng)的名字 --> <name>Windows XP</name> <!--激活profile的操作系統(tǒng)所屬家族(如 'windows') --> <family>Windows</family> <!--激活profile的操作系統(tǒng)體系結(jié)構(gòu) --> <arch>x86</arch> <!--激活profile的操作系統(tǒng)版本 --> <version>5.1.2600</version> </os> <!--如果Maven檢測(cè)到某一個(gè)屬性(其值可以在POM中通過(guò)${名稱(chēng)}引用),其擁有對(duì)應(yīng)的名稱(chēng)和值,Profile就會(huì)被激活。 --> <!-- 如果值字段是空的,那么存在屬性名稱(chēng)字段就會(huì)激活profile,否則按區(qū)分大小寫(xiě)方式匹配屬性值字段 --> <property> <!--激活profile的屬性的名稱(chēng) --> <name>profileProperty</name> <!--激活profile的屬性的值 --> <value>dev</value> </property> <!--提供一個(gè)文件名,通過(guò)檢測(cè)該文件的存在或不存在來(lái)激活profile。missing檢查文件是否存在,如果不存在則激活profile。 --> <!--另一方面,exists則會(huì)檢查文件是否存在,如果存在則激活profile。 --> <file> <!--如果指定的文件存在,則激活profile。 --> <exists>/usr/local/hudson/hudson-home/jobs/maven-guide-zh-to-production/workspace/</exists> <!--如果指定的文件不存在,則激活profile。 --> <missing>/usr/local/hudson/hudson-home/jobs/maven-guide-zh-to-production/workspace/</missing> </file> </activation> <properties> <!-- 該 profile 的映射路徑 --> <profiles.active>dev</profiles.active> <!-- 眾多參數(shù)配置 --> <db.driver>com.mysql.jdbc.Driver</db.driver> <db.url>jdbc:mysql://localhost:3306/test</db.url> <db.username>root</db.username> <db.password>root</db.password> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-quartz</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.43</version> </dependency> </dependencies> <!-- 打包配置 build --> <build> <resources> <!-- 配置一個(gè) resource --> <resource> <!-- 資源文件所在的路徑 --> <directory>src/main/resources/</directory> <!-- 打包自動(dòng)忽略以下資源文件,不會(huì)被打包進(jìn)來(lái) --> <excludes> <exclude>config/dev/*</exclude> <exclude>config/pro/*</exclude> <exclude>config/test/*</exclude> </excludes> <!-- 包含進(jìn)來(lái),防止打包時(shí)忽略掉除環(huán)境配置文件以外的對(duì)象 --> <includes> <include>views/*</include> </includes> </resource> <resource> <!--這里是關(guān)鍵! 根據(jù)不同的環(huán)境,把對(duì)應(yīng)文件夾里的配置文件打包--> <directory>src/main/resources/config/${profiles.active}</directory> </resource> </resources> </build> </profile> <profile> <id>pro</id> <properties> <profiles.active>pro</profiles.active> <!-- 眾多參數(shù)配置 --> </properties> </profile> <profile> <id>test</id> <properties> <profiles.active>test</profiles.active> <!-- 眾多參數(shù)配置 --> </properties> </profile> </profiles> <!-- 全局 build --> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build>
四、springboot 打包配置
SpringBoot 自帶Tomcat
,所以我們的項(xiàng)目可以單獨(dú)部署,不需要依賴 Window、Linux 系統(tǒng)中的服務(wù)器,所以打包出來(lái)的 Jar 包是可以直接運(yùn)行的
。
打包插件
SpringBoot 項(xiàng)目可以通過(guò) maven 的插件進(jìn)行打包,分為兩種情況:
(1)項(xiàng)目以 spring-boot-starter-parent 作為 parent
<plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin>
(2)項(xiàng)目不以 spring-boot-starter-parent 作為 parent
有時(shí)項(xiàng)目的 parent 不是 spring-boot-starter-parent,而是自定義的配置,此時(shí) spring-boot-maven-plugin 插件不能直接使用,需要做一些修改。
<plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <version>2.0.4.RELEASE</version> <configuration> <!-- 打包出來(lái)的jar/war就是可執(zhí)行的 --> <executable>true</executable> </configuration> <executions> <execution> <goals> <goal>repackage</goal> </goals> </execution> </executions> </plugin>
經(jīng)過(guò)這樣配置,就可以進(jìn)行打包了。
1、Maven 項(xiàng)目結(jié)構(gòu)
Maven 項(xiàng)目的標(biāo)準(zhǔn)目錄結(jié)構(gòu):
構(gòu)建 Maven 項(xiàng)目的時(shí)候,如果沒(méi)有進(jìn)行特殊的配置,Maven 會(huì)按照標(biāo)準(zhǔn)的目錄結(jié)構(gòu)查找和處理各種類(lèi)型文件。
(1) src/main/java 和 src/test/java 這兩個(gè)目錄中的所有 *.java 文件會(huì)分別在 compile 和 test-comiple 階段被編譯,編譯結(jié)果分別放到了 target/classes 和 targe/test-classes 目錄中,但是這兩個(gè)目錄中的其他文件都會(huì)被忽略掉
。
(2) src/main/resouces 和 src/test/resources 這兩個(gè)目錄中的文件也會(huì)分別被復(fù)制到 target/classes 和target/test-classes 目錄中
。
在 springboot 項(xiàng)目中,打包插件默認(rèn)會(huì)把這個(gè)目錄中的所有內(nèi)容打入到 jar 包或者 war 包中,然后放在 BOOT-INF 目錄下。
2、打包時(shí)資源文件的配置
(1)打包 src/main/java 目錄下的 xml
一般情況下,我們用到的資源文件(各種xml,properites,xsd文件等)都放在src/main/resources下面,利用 maven 打包時(shí),maven 能把這些資源文件打包到相應(yīng)的 jar 或者 war 里。
有時(shí)候,比如 mybatis 的 mapper.xml 文件,我們習(xí)慣把它和 Mapper.java 放一起,都在 src/main/java 下面,這樣利用 maven 打包時(shí),就需要修改 pom.xml 文件,來(lái)把 mapper.xml 文件一起打包進(jìn) jar 或者 war 里了,否則,這些文件不會(huì)被打包的。(maven認(rèn)為src/main/java只是java的源代碼路徑)
例如:
默認(rèn)情況下,執(zhí)行 mvn clean package 打包命令后在 target\classes 目錄下不會(huì)把 UserMapper.xml 打包到下 mapper 目錄下。
解決方法有如下幾種:
1)配置 POM.XML 的 resource 把 xml 也打包到 mapper 目錄下
<build> <!-- 資源目錄 --> <resources> <resource> <!-- 設(shè)定主資源目錄 --> <directory>src/main/java</directory> <!-- maven default生命周期,process-resources階段執(zhí)行maven-resources-plugin插件的resources目標(biāo)處理主資源目下的資源文件時(shí),只處理如下配置中包含的資源類(lèi)型 --> <includes> <include>**/*.xml</include> </includes> <!-- maven default生命周期,process-resources階段執(zhí)行maven-resources-plugin插件的resources目標(biāo)處理主資源目下的資源文件時(shí),不處理如下配置中包含的資源類(lèi)型(剔除下如下配置中包含的資源類(lèi)型)--> <excludes> <exclude>**/*.yaml</exclude> </excludes> <!-- maven default生命周期,process-resources階段執(zhí)行maven-resources-plugin插件的resources目標(biāo)處理主資源目下的資源文件時(shí),指定處理后的資源文件輸出目錄,默認(rèn)是${build.outputDirectory}指定的目錄--> <!--<targetPath>${build.outputDirectory}</targetPath> --> <!-- maven default生命周期,process-resources階段執(zhí)行maven-resources-plugin插件的resources目標(biāo)處理主資源目下的資源文件時(shí),是否對(duì)主資源目錄開(kāi)啟資源過(guò)濾 --> <filtering>true</filtering> </resource> </resources> </build>
2)maven-resources-plugin 插件
為了使項(xiàng)目結(jié)構(gòu)更為清晰,Maven區(qū)別對(duì)待Java代碼文件和資源文件,maven-compiler-plugin用來(lái)編譯Java代碼,maven-resources-plugin則用來(lái)處理資源文件。
默認(rèn)的主資源文件目錄是src/main/resources,很多用戶會(huì)需要添加額外的資源文件目錄,這個(gè)時(shí)候就可以通過(guò)配置maven-resources-plugin來(lái)實(shí)現(xiàn)。
<!-- 利用此plugin,把源代碼中的xml文件,打包到相應(yīng)位置,這里主要是為了打包Mybatis的mapper.xml文件--> <plugin> <artifactId>maven-resources-plugin</artifactId> <version>2.5</version> <executions> <execution> <id>copy-xmls</id> <phase>process-sources</phase> <goals> <goal>copy-resources</goal> </goals> <configuration> <outputDirectory>${basedir}/target/classes</outputDirectory> <resources> <resource> <directory>${basedir}/src/main/java</directory> <includes> <include>**/*.xml</include> </includes> </resource> </resources> </configuration> </execution> </executions> </plugin>
3)build-helper-maven-plugin 插件
<!-- 利用此plugin,把源代碼中的xml文件,打包到相應(yīng)位置,這里主要是為了打包Mybatis的mapper.xml文件 --> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>build-helper-maven-plugin</artifactId> <version>1.8</version> <executions> <execution> <id>add-resource</id> <phase>generate-resources</phase> <goals> <goal>add-resource</goal> </goals> <configuration> <resources> <resource> <directory>src/main/java</directory> <includes> <include>**/*.xml</include> </includes> </resource> </resources> </configuration> </execution> </executions> </plugin>
(2)src/main/resources 目錄下的 xml 等資源文件不被打包
默認(rèn) resources 目錄下的文件都會(huì)被打包,如果想 resources 目錄下的 xml 文件不被打包,可通過(guò)如下配置:
<!--過(guò)濾resource下的文件--> <resources> <resource> <directory>src/main/resources</directory> <includes> <include>*.properties</include> <!--打包properties文件--> </includes> <excludes> <exclude>*.xml</exclude> <!--過(guò)濾xml與yaml文件--> <exclude>*.yaml</exclude> </excludes> </resource> </resources>
當(dāng)然也可以通過(guò)插件來(lái)實(shí)現(xiàn):
<plugin> <artifactId>maven-resources-plugin</artifactId> <executions> <execution> <id>copy-resources</id> <phase>validate</phase> <goals> <goal>copy-resources</goal> </goals> <configuration> <!-- 并把文件復(fù)制到target/conf目錄下--> <outputDirectory>${project.build.directory}/conf</outputDirectory> <resources> <resource> <directory>src/main/resources</directory> <!-- 指定不需要處理的資源 <excludes> <exclude>WEB-INF/*.*</exclude> </excludes> --> <excludes> <exclude>**/*.xml</exclude> </excludes> <filtering>true</filtering> </resource> </resources> </configuration> </execution> </executions> </plugin>
實(shí)現(xiàn)的效果如下:
編譯好之后,會(huì)在target目錄下生成 conf 目錄并且把 resources 目錄下的所有文件都自動(dòng)拷貝到 target/conf/ 目錄下。
四、倉(cāng)庫(kù)配置
五、發(fā)布配置
六、pom 項(xiàng)目依賴、繼承與聚合
1、項(xiàng)目之間的相互依賴
現(xiàn)在有兩個(gè)項(xiàng)目,HelloWorld1 和 HelloWorld2,如果 HelloWorld1 要引用 HelloWorld2 中的方法,也就是 HelloWorld1 要依賴 HelloWorld2。做法如下:
(1)在 helloworld1 項(xiàng)目之中,執(zhí)行打包命令將當(dāng)前項(xiàng)目打包成可依賴的 jar 包
,并放進(jìn)本地倉(cāng)庫(kù)當(dāng)中;
(2)在helloworld2 項(xiàng)目的 pom.xml 之中,加入 helloworld1 依賴。helloworld 的 jar 包坐標(biāo):
<dependency> <groupId>cn.edu.ouc</groupId> <artifactId>HelloWorld</artifactId> <version>1.0-SNAPSHOT</version> </dependency>
(3)通過(guò) import 導(dǎo)入 jar 包,就成功的引入我們自定義的項(xiàng)目 jar 包。這樣就可以使用
helloworld1 項(xiàng)目的所有方法。
如何打包成可依賴的 jar 包
在 SpringBoot 工程中使用 spring-boot-maven-plugin 的默認(rèn)配置 build,那么所生成的 jar 包雖然是可執(zhí)行的,但卻是不可被依賴的
。
通過(guò)修改 pom.xml 中 spring-boot-maven-plugin 的配置,可以讓所在工程一次打包生成兩個(gè) jar 包,其中 XXX.jar 可作為其它工程的依賴,XXX-exec.jar 可被執(zhí)行。
<plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <version>2.0.4.RELEASE</version> <executions> <execution> <goals> <!--可以把依賴的包都打包到生成的Jar包中 --> <goal>repackage</goal> </goals> </execution> </executions> <!--生成可執(zhí)行 Jar 包 --> <configuration> <classifier>exec</classifier> </configuration> </plugin>
classifier 指定了可執(zhí)行 jar 包的名字,默認(rèn)的 jar 包則作為可被其他程序依賴的 Artifact。配置完成后對(duì)項(xiàng)目進(jìn)行打包,會(huì)生成以下兩個(gè) jar 包。
SpringbootDemo-1.0-SNAPSHOT.jar 是一個(gè)可以被其他項(xiàng)目依賴的 jar,
SpringbootDemo-1.0-SNAPSHOT-exec.jar 是一個(gè)可執(zhí)行的 jar。
對(duì)其分別解壓,可以看到 class 路徑是不同的:
2、maven 父子項(xiàng)目依賴的繼承
現(xiàn)在有兩個(gè)項(xiàng)目 A 和 B,繼承就是說(shuō) B 項(xiàng)目之中依賴的包 A 項(xiàng)目也可以使用。一般用于統(tǒng)一管理依賴版本號(hào)
等
具體實(shí)現(xiàn)如下:
(1)創(chuàng)建父工程 parent,打包方式為 pom
,并在其中依賴 junit.jar,注意要將依賴寫(xiě)在 <dependencyManagement> 標(biāo)簽之中
。
Maven 提供了 <dependencyManagement> 元素既能讓子模塊繼承到父模塊的依賴配置,又能保證子模塊依賴的使用靈活性。
在 <dependencyManagement> 標(biāo)簽下的依賴聲明不會(huì)將依賴直接引入到父工程和子工程中,不過(guò)它能約束 dependencies 下的依賴配置;子模塊中只有在<dependenices> 標(biāo)簽中聲明的依賴才會(huì)被繼承并引入到子工程中
。
如下:
(2)在子工程 Helloworld 的 pom.xml 當(dāng)中添加父工程標(biāo)簽,這里的 <relativePath> 是父工程的 pom.xml 文件的位置
,其他是父工程的 gav。如下:
<parent> <groupId>org.apache.maven</groupId> <artifactId>parent</artifactId> <version>1.0-SNAPSHOT</version> <relativePath>../parent/pom.xml</relativePath> </parent>
(3)在子工程當(dāng)中,聲明需要使用父類(lèi)當(dāng)中的哪些 jar 包,聲明寫(xiě)在 pom.xml 的 <dependenices> 標(biāo)簽之中,子模塊不需要配置 jar 包的版本和作用域,只需配置 groupId 和 artifactId
。如下:
可以看到有一個(gè)向上繼承的符號(hào),說(shuō)明繼承已經(jīng)成功了。更新之后發(fā)現(xiàn) junit 已經(jīng)導(dǎo)入。
3、多模塊項(xiàng)目的聚合
如果一個(gè)項(xiàng)目有多個(gè)模塊,也叫做多重模塊,或者合成項(xiàng)目。
如果不用聚合那么每次打包每個(gè)模塊都要運(yùn)行,但是用來(lái)聚合后,只運(yùn)行一次就行了。
<project> <modelVersion>4.0.0<modelVersion> <groupId>cn.edu.ouc<groupId> <artifactId>my-parent<artifactId> <version>2.0<version> <modules> <!-- 模塊相對(duì)于pom文件的位置--> <module>my-project1<module> <module>my-project2<module> <modules> <project>
如果多個(gè)模塊有相同的內(nèi)容,那么就可以用一個(gè)父模塊來(lái)實(shí)現(xiàn)相同的內(nèi)容,其他模塊只要繼承父模塊就行了
。
父模塊中把所有 jar 包都引用進(jìn)來(lái),子模塊就不用配置 jar 包的版本和作用域了。(繼承)
反應(yīng)堆:
在一個(gè)多模塊的 Maven 項(xiàng)目中,反應(yīng)堆是指所有模塊組成的一個(gè)構(gòu)建結(jié)構(gòu)。反應(yīng)堆包含了各個(gè)模塊之間的繼承與依賴關(guān)系,從而能夠自動(dòng)計(jì)算出合理的模塊構(gòu)建順序。
<modules> <module>account-email</module> <module>account-persist</module> <module>account-parent</module> </modules>
實(shí)際的構(gòu)建順序?yàn)椋?~parent, ~email, ~persist。可見(jiàn)構(gòu)建的順序并不是聲明的順序。
該例中 account-email 和 account-persist 都依賴于 account-parent,那么 account-parent 就必須在另外兩個(gè)模塊之前構(gòu)建。
實(shí)際的構(gòu)建順序是這樣的:Maven 按聲明順序讀取 POM,如果 POM 沒(méi)有依賴模塊,那么就構(gòu)建該模塊,否則就先構(gòu)建其依賴的模塊;如果依賴的模塊還依賴于其他模塊,則進(jìn)一步構(gòu)建依賴的依賴
。
模塊之間的關(guān)系將反應(yīng)堆構(gòu)成一個(gè)有向非循環(huán)圖,各個(gè)模塊是該圖的節(jié)點(diǎn),依賴關(guān)系構(gòu)成又向邊,這個(gè)圖不允許出現(xiàn)循環(huán),因此當(dāng)出現(xiàn) A 依賴于 B,B 又依賴于 A 的情況時(shí) Maven 就會(huì)報(bào)錯(cuò)
。
4、聚合與繼承的關(guān)系
(1)區(qū)別 :
1)對(duì)于聚合模塊來(lái)說(shuō),它知道有哪些被聚合的模塊,但那些被聚合的模塊不知道這個(gè)聚合模塊的存在。
2)對(duì)于繼承關(guān)系的父 POM 來(lái)說(shuō),它不知道有哪些子模塊繼承與它,但那些子模塊都必須知道自己的父 POM是什么。
(2)共同點(diǎn) :
1)聚合 POM 與繼承關(guān)系中的父 POM 的 packaging 都是 pom
;
2)聚合模塊與繼承關(guān)系中的父模塊除了 POM 之外都沒(méi)有實(shí)際的內(nèi)容
。
現(xiàn)有的實(shí)際項(xiàng)目往往是一個(gè)POM既是聚合POM又是父POM,這么做主要是為了方便。
到此這篇關(guān)于maven的pom文件與打包詳解的文章就介紹到這了,更多相關(guān)maven pom文件與打包內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
基于Spring中的線程池和定時(shí)任務(wù)功能解析
下面小編就為大家?guī)?lái)一篇基于Spring中的線程池和定時(shí)任務(wù)功能解析。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-09-09Springboot整合第三方登錄功能的實(shí)現(xiàn)示例
本文主要介紹了Springboot整合第三方登錄功能的實(shí)現(xiàn)示例,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-01-01Java實(shí)現(xiàn)圖書(shū)管理系統(tǒng)的示例代碼
這篇文章將通過(guò)Java實(shí)現(xiàn)一個(gè)簡(jiǎn)答的圖書(shū)管理系統(tǒng),本圖書(shū)管理系統(tǒng)用對(duì)象數(shù)組的方式來(lái)提供操作方法,比較特別,建議新手學(xué)習(xí),這對(duì)理解Java面向?qū)ο笥泻艽髱椭?/div> 2022-11-11最新評(píng)論