一文掌握Java開發(fā)工具Maven(簡單上手)
Maven
如果作為一個Java程序員,那么在日常的開發(fā)過程中,maven是很常見的項目構(gòu)建工具。maven可以極大的提高我們的開發(fā)效率,幫助我們簡化開發(fā)過程中一些解決依賴和項目部署的相關(guān)問題,所以學習掌握maven的相關(guān)知識是非常有必要的。
本文從入門安裝開始,逐步深入講解maven的相關(guān)知識。
1、安裝maven
首先我們需要準備好安裝包,這里推薦在官網(wǎng)下載:maven官網(wǎng)下載地址
我這里下載的是3.8.1版本的maven,不同版本的maven配置過程基本是一樣的。
1.1 Windows安裝
首先將maven安裝包解壓,根據(jù)自己的習慣選擇解壓目錄,后續(xù)配置需要使用到解壓的目錄。我這里解壓到了D:\software\Maven,之后的配置也是從這里開始的。
首先要配置Windows的環(huán)境變量,如果是最新版的Windows 10,那么右鍵單擊屬性后會出現(xiàn)如下頁面,點擊高級系統(tǒng)設(shè)置=>環(huán)境變量即可:
接下來就是配置系統(tǒng)變量,首先配置MAVEN_HOME,在系統(tǒng)變量窗口點擊新建,然后輸入變量名和變量值,變量名為MAVEN_HOME,變量值就是maven的安裝路徑,可以通過瀏覽目錄找到自己的maven安裝位置。
接下來配置系統(tǒng)變量中的path變量,首先選中path變量,然后點擊編輯,彈出編輯path變量的窗口,點擊新建,在最后一行輸入如下參數(shù):%MAVEN_HOME%\bin
此時maven的環(huán)境變量已經(jīng)配置完成了,可以打開cmd窗口,運行mvn -v查看配置是否成功。
1.2 Linux安裝
將下載好的文件上傳至云服務(wù)器,我這里直接上傳到了/usr/local/目錄下,然后直接將其解壓
tar -zxvf apache-maven-3.8.1-bin.tar.gz
接下來就是配置環(huán)境變量,在/etc/profile文件中添加環(huán)境變量,內(nèi)容如下:
export MAVEN_HOME=/usr/local/apache-maven-3.8.1 export PATH=$PATH:$MAVEN_HOME/bin
然后再運行source /etc/profile使其生效即可。
然后可以運行mvn -v命令查看是否配置成功:
1.3 簡單配置
當安裝完maven以后,我們還需要配置maven的鏡像和我們本地倉庫的地址,maven的全局配置文件是安裝目錄下的conf/settings.xml文件,下面的配置都是在該文件中進行的。
1.3.1 配置本地倉庫路徑
本地倉庫是我們新建maven項目并添加依賴后,那些依賴的jar包下載到的位置。
首先看看配置文件,本地倉庫路徑不配置的話默認為當前用戶目錄下的./m2文件夾下的repository目錄,我們最好自己配置下,管理maven倉庫的位置。
配置的話選定自己的倉庫目錄,然后添加在配置文件中即可,例如我這里是這樣配置的:
<localRepository>D:\software\Maven\MavenRepository</localRepository>
Linux的話需要注意路徑的方式:
<localRepository>/usr/local/apache-maven-3.8.1/MavenRepository</localRepository>
1.3.2 配置鏡像
如果我們不配置國內(nèi)鏡像的話,那么maven下載依賴可能會非常非常慢,所以我們這里要配置鏡像,這里我配置的是阿里云的鏡像:
<mirrors> <mirror> <id>alimaven</id> <name>aliyun maven</name> <url>https://maven.aliyun.com/repository/public</url> <mirrorOf>central</mirrorOf> </mirror> </mirrors>
當然也可以配置些其他的鏡像,例如華為的鏡像。
1.4 idea配置
我們通常都是使用idea進行項目的開發(fā)工作,所以這里接著介紹下idea如何配置我們自己安裝的maven,而不是使用idea自帶的maven。
首先點擊Files->settins打開配置窗口:
然后找到maven的配置,將maven的安裝路徑和配置文件以及本地倉庫的配置均修改為我們自己安裝的maven即可:
此外還要配置每個新建項目的maven配置,點擊New Projects Settings -> Settings for New Projects:
也是進行相同的配置:
配置完成以后,我們以后就可以使用自己安裝的maven在idea中開發(fā)項目了。
2、Maven簡單上手
雖然我們可以使用idea簡化項目的開發(fā),但是我們還是要簡單了解一下不借助idea如何新建maven項目的。
首先來看看maven的項目結(jié)構(gòu):
src |--main |--java 源代碼目錄 |--resources 資源目錄 |--test |--java 測試代碼目錄 |--resources 測試資源目錄 target |--classes 編譯后的class文件目錄 |--test-classes 編譯后的測試class文件目錄 pom.xml Maven工程配置文件
其中src、target、pom是同級目錄,接下來我們嘗試手動創(chuàng)建這些目錄:
我們首先來看看pom.xml的基本配置:
<?xml version="1.0" encoding="UTF-8"?> <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>cn.wygandwdn</groupId> <artifactId>learn_maven</artifactId> <version>1.0-SNAPSHOT</version> </project>
然后接著在src/java目錄下新建一個Hello.java:
import java.util.*; class Hello { public static void main(String[] args) { System.out.println("Hello Maven"); } }
然后在項目的根目錄下運行mvn compile試試,也就是src文件對應的目錄:
出現(xiàn)BUILD SUCCESS就是構(gòu)建成功了,接下來看看都構(gòu)建出來了哪些文件:
可以看出,maven自動為我們將Hello.java構(gòu)建成了Hello.class并放到了target/classes目錄下。
是不是很簡單,當我們使用idea之后,這些工作都不需要我們來做,都是自動化完成的。
3、Maven生命周期
如果我們打開idea,查看maven的話,會發(fā)現(xiàn)maven的幾個生命周期:
這些生命周期實際上分為三部分,分別是:
- clean:為執(zhí)行以下工作做必要的清理,就是刪除out文件夾。
- default:真正進行項目編譯打包等工作的階段
- site: 生成項目報告,站點,發(fā)布站點
這三個生命周期又有各自詳細的生命周期。
clean生命周期又分為如下幾個階段:
- pre-clean:執(zhí)行一些需要在clean之前完成的工作
- clean:移除所有上一次構(gòu)建生成的文件
- post-clean:執(zhí)行一些需要在clean之后立刻完成的工作
default又分為如下幾個階段(和idea中顯示的正好對應,這是簡化版的生命周期):
- validate:驗證項目是否正確,所有必要的信息是否可用
- compile:編譯項目的源代碼test:使用合適的單元測試框架測試編譯的源代碼,測試代碼不應該被打包或者部署
- package:將編譯后的代碼打包成可發(fā)布的格式,例如jar包
- verify:運行任意的檢查來驗證項目包是否有效且達到質(zhì)量標準
- install:安裝項目包到本地倉庫,這樣項目包可以用做其他本地項目的依賴
- deploy:將最終的項目包復制到遠程倉庫與其他開發(fā)者和項目共享
site生命周期又分為如下幾個階段:
- pre-site:執(zhí)行一些需要在生成站點文檔之前完成的工作
- site:生成項目的站點文檔
- post-site: 執(zhí)行一些需要在生成站點文檔之后完成的工作,并且為部署做準備
- site-deploy:將生成的站點文檔部署到特定的服務(wù)器上
各個生命周期相互獨立,互不影響,一個生命周期的階段前后依賴。
當我們運行maven命令時,例如運行mvn compile,只有該階段之前以及包括該階段在內(nèi)的所有階段才會被執(zhí)行,在compile之后的test、package等是不會被執(zhí)行的。
常用的maven命令:
命令 | 說明 |
---|---|
mvn -v | 顯示版本信息 |
mvn clean | 清理項目產(chǎn)生的臨時文件,一般是模塊下的target目錄 |
mvn compile | 編譯源代碼,一般編譯模塊下的src/main/java目錄 |
mvn package | 項目打包工具,會在target目錄下生成jar包或者war包 |
mvn test | 測試命令,或執(zhí)行src/test/java/下junit的測試用例 |
mvn install | 將打包的jar/war文件復制到本地倉庫,供其他模塊使用 |
mvn deploy | 將打包的文件發(fā)布到遠程服務(wù)器,供其他人員下載依賴 |
mvn site | 生成項目相關(guān)信息的網(wǎng)站 |
mvn dependency:tree | 打印出項目的整個依賴樹 |
mvn archetype:generate | 創(chuàng)建maven的普通Java項目 |
4、POM文件詳解
4.1、基礎(chǔ)介紹
首先我們來看看一個簡單的POM文件:
<?xml version="1.0" encoding="UTF-8"?> <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>cn.wygandwdn</groupId> <artifactId>learn_maven</artifactId> <version>1.0-SNAPSHOT</version> <packaging>pom</packaging></project> </project>
這是maven項目構(gòu)建后產(chǎn)生的最基礎(chǔ)的pom文件,接下來講講這幾個標簽的含義:
- modelVersion:描述pom文件遵循哪個版本的項目描述符,描述了當前pom模型的版本,對于maven2和maven3來說,它只能是4.0.0;它是強制性的
- 接下來的groupId、artifactId、version是唯一定位一個項目的,相當于項目的坐標:
- groupId:團體組織的標識符,它以創(chuàng)建這個項目的組織名稱的逆向域名開頭,例如我們域名為wygandwdn.cn,這里就是cd.wygandwdn,同時也對應著Java的包結(jié)構(gòu)
- artifactId:單獨項目的標識符,一個組織可能會有多個項目,那么這個artifactId就是描述一個組織名下的不同項目,不要在artifactId中包含點號(.)
- version:項目的版本packing:項目的打包類型,默認為jar,描述了項目打包后的輸出。類型為jar的項目產(chǎn)生一個jar文件,類型war的項目產(chǎn)生一個web應用;類型為pom的話,說明該項目為一個聚合項目,包含多個子項目
Maven的version中通常出現(xiàn)如下幾個特殊的字符串:SNAPSHOT、LATEST、RELEASE,例如我們使用idea創(chuàng)建的默認maven項目的版本通常為:1.0-SNAPSHOT。各個版本的含義和邏輯為:
- SNAPSHOT:表示項目開發(fā)過程中的快照版本,不穩(wěn)定的版本
- LATEST:某個特定構(gòu)件的最新版本,這個發(fā)布可能是一個發(fā)布版,也可能是一個snapshot版本,具體看哪個時間最后
- RELEASE:指最后一個發(fā)布版,穩(wěn)定版
4.2、dependencies&dependency
我們之前說過,maven最終的功能就是管理依賴,那么這些依賴就是通過dependencies&dependency標簽來定義的。
例如:
<?xml version="1.0" encoding="UTF-8"?><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>cn.wygandwdn</groupId> <artifactId>learn_maven</artifactId> <version>1.0-SNAPSHOT</version> <packaging>pom</packaging> <dependencies> <!-- 每個dependency都對應這一個jar包 --> <dependency> <!--一般情況下,maven是通過groupId、artifactId、version這三個元素值(俗稱坐標)來檢 索該構(gòu)件, 然后引入你的工程。如果別人想引用你現(xiàn)在開發(fā)的這個項目(前提是已開發(fā)完畢并發(fā)布到了遠程倉庫),--> <!--就需要在他的pom文件中新建一個dependency節(jié)點,將本項目的groupId、artifactId、 version寫入, maven就會把你上傳的jar包下載到他的本地 --> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <!-- 默認值為jar,它通常代表依賴關(guān)系的文件名的擴展 --> <type>jar</type> <!-- 依賴范圍 --> <scope>complie</scope> <!-- 設(shè)置 依賴是否可選,默認為false,即子項目默認都繼承。如果為true,則子項目必需顯示的引入 --> <optional>false</optional> <!-- 依賴排除--> <exclusions> <exclusion> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> </exclusion> </exclusions> </dependency> </dependencies> </project>
上面的groupId、artifactId、version是定位jar包的坐標,通過這個唯一的標識,maven會自動去倉庫引入依賴。
- type:代表項目依賴的類型,例如jar、war、pom等。
- scope:代表的是這些依賴的作用范圍,分別如下:
compile(默認編譯范圍):該范圍是默認依賴范圍,此依賴范圍對于編譯、測試、運行三種classpath都有效,也就是說該范圍下的jar包在編譯、測試、運行和打包時都可以使用。
test(測試依賴范圍):test范圍的依賴只對測試classpath有效,在編譯主代碼和項目運行時,都將無法使用該依賴,最典型的例子就是junit。junit是測試時才需要的依賴,所以它的依賴范圍需要指定為test。如果不加范圍也不會報錯,但是該依賴會被加入到編譯和運行的classpath中,會浪費一定的空間
<dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.7</version> <scope>test</scope> </dependency>
provided(已提供依賴):使用該依賴范圍時,只對編譯和測試的classpath有效,對運行時classpath無效,最典型的例子就是servlet-api,編譯和測試項目時都需要該依賴,但是在運行時,web容器已經(jīng)提供該依賴,所以運行時就不需要此以愛,如果不顯示指定該依賴范圍,并且容器依賴的版本和maven不一致的話,可能會造成沖突。
<dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>4.0.1</version> <scope>provided</scope> </dependency>
runtime(運行時依賴范圍):使用該依賴范圍時,只對測試和運行的classpath有效,對編譯時的classpath無效,典型的例子就是jdbc驅(qū)動的實現(xiàn),項目主代碼編譯的時候只需要jdk提供的jdbc接口,只有在測試和運行時才需要實現(xiàn)上述接口的具體jdbc驅(qū)動。
<dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.25</version> <scope>runtime</scope> </dependency>
- optional:設(shè)置依賴是否可選,默認為false,即子項目默認都繼承。如果為true,則子項目必需顯示的引入
- exclusions:該標簽主要用于依賴的排除,該標簽包含s,說明可以排除多個依賴,具體排除的依賴通過exclusion標簽定義,exclusion中通過groupId和artifactId定位要排除的依賴。
4.3、dependencyManagement
dependencyManagement通常會在父工程中定義,目的就是為了統(tǒng)一各個子模塊的依賴版本,也就是管理子項目中依賴的jar包的版本。
- 該標簽只是聲明依賴,并不是實際的引入
- 子項目需要顯式的聲明需要用的依賴,如果不再子項目中聲明依賴,那么子項目是不會從父項目中繼承依賴的
- 只有在子項目中寫了該依賴項,并且沒有指定具體版本,才會從父項目中繼承該項,并且version和scope都讀取自父pom;另外如果子項目中指定了版本號,那么會使用子項目中指定的jar版本
在我們創(chuàng)建聚合工程時,使用該標簽非常有用
4.4、properties
properties定義了一些在pom中使用的占位符,相當于一些公共的屬性,一般用于指定各個依賴的版本號。
例如:
<?xml version="1.0" encoding="UTF-8"?> <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>cn.wygandwdn</groupId> <artifactId>learn_maven</artifactId> <version>1.0-SNAPSHOT</version> <packaging>pom</packaging> <properties> <mysql.version>8.0.22</mysql.version> </properties> <dependencies> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>${mysql.version}</version> </dependency> </dependencies> </project>
當我們定義mysql連接依賴時,將其對應的版本通過properties來定義,那么以后修改mysql連接依賴時,只需要修改標簽中的依賴即可,不需要再去對應的依賴處修改。
properties標簽內(nèi)一般根據(jù)依賴的名稱來自定義標簽,通過"."進行分割,然后在dependency中引入即可。
當我們引入眾多的依賴時,使用properties非常有用,通過properties定義版本,那么修改時,只統(tǒng)一修改這里的版本即可。其子項目也可以使用properties里定義的標簽。
4.5、構(gòu)建配置
來看看build標簽下的內(nèi)容:
<build> <!-- 產(chǎn)生的構(gòu)件的文件名,默認值是${artifactId}-${version}--> <finalName>myPorjectName</finalName> <!-- 構(gòu)建產(chǎn)生的所有文件存放的目錄,默認為${basedir}/target,即項目根目錄下的target --> <directory>${basedir}/target</directory> <!--項目相關(guān)的所有資源路徑列表,例如和項目相關(guān)的配置文件、屬性文件,這些資源被包含在最終的打包文件里--> <!--項目源碼目錄,當構(gòu)建項目的時候,構(gòu)建系統(tǒng)會編譯目錄里的源碼。該路徑是相對于pom.xml的相對路徑--> <sourceDirectory>${basedir}\src\main\java</sourceDirectory> <!--項目單元測試使用的源碼目錄,當測試項目的時候,構(gòu)建系統(tǒng)會編譯目錄里的源碼。該路徑是相對于pom.xml的相對路徑--> <testSourceDirectory>${basedir}\src\test\java</testSourceDirectory> <!--被編譯過的應用程序class文件存放的目錄--> <outputDirectory>${basedir}\target\classes</outputDirectory> <!--被編譯過的測試class文件存放的目錄--> <testOutputDirectory>${basedir}\target\test-classes</testOutputDirectory> <!-- 以上配置都有默認值,就是約定好了目錄就這么建 --> <resources> <!--處理src中填寫的配置文件,防止打包的時候它們被過濾掉--> <!--本初配置的含義就是不對src/main/java下的../*.xml資源進行篩選,對src/main/java下的../*.properties進行過濾--> <resource> <directory>src/main/java</directory> <!--指定要包含的文件作為指定目錄下的資源--> <includes> <include>**/*.properties</include> <include>**/*.xml</include> </includes> <!--指定要忽略的資源,如果includes和excludes包含同樣的文件,那么excludes中的定義生效--> <excludes> <exclude>**/*.properties</exclude> </excludes> <filtering>false</filtering> </resource> <resource> <directory>src/main/resources</directory> <includes> <include>**/*.properties</include> <include>**/*.xml</include> </includes> <filtering>false</filtering> </resource> </resources> <!--單元測試相關(guān)的所有資源路徑,配置方法與resources類似 --> <testResources> <testResource> <targetPath /> <filtering /> <directory /> <includes /> <excludes /> </testResource> </testResources> <!--使用的插件列表--> <plugins> <plugin> <!--具體在插件使用中了解--> </plugin> </plugins> <!--主要定義插件的共同元素、擴展元素集合,類似于dependencyManagement--> <!--所有繼承于此項目的子項目都能使用。該插件配置項直到被引用時才會被解析或綁定到生命周期--> <!--給定插件的任何本地配置都會覆蓋這里的配置--> <pluginManagement> <plugins>...</plugins> </pluginManagement> </build>
resources主要處理資源過濾的問題,這里詳細解釋下resource標簽下的各個屬性:
- directory:資源過濾對應的目錄
- includes:資源過濾對哪些資源生效
- excludes:資源過濾對哪些資源不生效
- filtering:true或者false(具體情況可以自己在實際項目中測驗一下,這里直接給出測驗后的結(jié)論)
true就是對includes下定義的資源過濾,對excludes下定義的資源不過濾
false就是對includes下定義的資源不過濾,對excludes下定義的資源過濾
當我們想引入支付包的jar包或者oracle的連接驅(qū)動時,可以自己配置jar包的路徑,然后引入項目,具體的配置如下:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <!--是否被子項目繼承,默認為true--> <inherited>true</inherited> <configuration> <source>1.8</source> <target>1.8</target> <encoding>UTF-8</encoding> <compilerArguments> <!-- 本地jar,支付寶jar包放到 src/main/webapp/WEB-INF/lib 文件夾下, 如果沒有配置,本地沒問題,但是線上會找不到sdk類 為什么要引入,因為支付寶jar包再中央倉庫沒有,再比如oracle連接驅(qū)動的jar --> <extdirs>${project.basedir}/src/main/webapp/WEB-INF/lib</extdirs> </compilerArguments> </configuration> </plugin>
從這里我們可以看出,不管是引入依賴,還是引入插件,都是通過groupId、artifactId進行唯一的標識,來確定我們引入的具體的依賴或者插件。
4.6、倉庫配置
<repositories> <repository> <id>alimaven</id> <name>aliyun maven</name> <url>http://maven.aliyun.com/nexus/content/groups/public/</url> <releases> <enabled>true</enabled> </releases> <snapshots> <enabled>false</enabled> </snapshots> </repository> </repositories>
pom.xml里面的倉庫與setting.xml里的倉庫功能是一樣的。主要的區(qū)別在于,pom里的倉庫是個性化的。比如一 家大公司里的setting文件是公用的,所有項目都用一個setting文件,但各個子項目卻會引用不同的第三方庫,所 以就需要在pom.xml里設(shè)置自己需要的倉庫地址。
4.7、項目配置信息(了解即可)
<!--項目的名稱, Maven產(chǎn)生的文檔用 --> <name>banseon-maven </name> <!--項目主頁的URL, Maven產(chǎn)生的文檔用 --> <url>http://www.clf.com/ </url> <!--項目的詳細描述, Maven 產(chǎn)生的文檔用。 當這個元素能夠用HTML格式描述時 --> <!--(例如,CDATA中的文本會被解析器忽略,就可以包含HTML標簽),不鼓勵使用純文本描述。 --> <!-- 如果你需要修改產(chǎn)生的web站點的索引頁面,你應該修改你自己的索引頁文件,而不是調(diào)整這里的文檔。 --> <description>A maven project to study maven. </description> <!--項目創(chuàng)建年份,4位數(shù)字。當產(chǎn)生版權(quán)信息時需要使用這個值。 --> <inceptionYear /> <!--項目相關(guān)郵件列表信息 --> <mailingLists> <!--該元素描述了項目相關(guān)的所有郵件列表。自動產(chǎn)生的網(wǎng)站引用這些信息。 --> <mailingList> <!--郵件的名稱 --> <name> Demo </name> <!--發(fā)送郵件的地址或鏈接,如果是郵件地址,創(chuàng)建文檔時,mailto: 鏈接會被自動創(chuàng)建 --> <post> clf@126.com</post> <!--訂閱郵件的地址或鏈接,如果是郵件地址,創(chuàng)建文檔時,mailto: 鏈接會被自動創(chuàng)建 --> <subscribe> clf@126.com</subscribe> <!--取消訂閱郵件的地址或鏈接,如果是郵件地址,創(chuàng)建文檔時,mailto: 鏈接會被自動創(chuàng)建 --> <unsubscribe> clf@126.com</unsubscribe> <!--你可以瀏覽郵件信息的URL --> <archive> http:/hi.clf.com/</archive> </mailingList> </mailingLists> <!--項目開發(fā)者列表 --> <developers> <!--某個項目開發(fā)者的信息 --> <developer> <!--SCM里項目開發(fā)者的唯一標識符 --> <id> HELLO WORLD </id> <!--項目開發(fā)者的全名 --> <name> banseon </name> <!--項目開發(fā)者的email --> <email> banseon@126.com</email> <!--項目開發(fā)者的主頁的URL --> <url /> <!--項目開發(fā)者在項目中扮演的角色,角色元素描述了各種角色 --> <roles> <role> Project Manager</role> <role>Architect </role> </roles> <!--項目開發(fā)者所屬組織 --> <organization> demo</organization> <!--項目開發(fā)者所屬組織的URL --> <organizationUrl>http://hi.clf.com/ </organizationUrl> <!--項目開發(fā)者屬性,如即時消息如何處理等 --> <properties> <dept> No </dept> </properties> <!--項目開發(fā)者所在時區(qū), -11到12范圍內(nèi)的整數(shù)。 --> <timezone> -5</timezone> </developer> </developers> <!--項目的其他貢獻者列表 --> <contributors> <!--項目的其他貢獻者。參見developers/developer元素 --> <contributor> <name /> <email /> <url /> <organization /> <organizationUrl /> <roles /> <timezone /> <properties /> </contributor> </contributors> <!--該元素描述了項目所有License列表。應該只列出該項目的license列表,不要列出依賴項目的license列表。 --> <!--如果列出多個license,用戶可以選擇它們中的一個而不是接受所有l(wèi)icense。 --> <licenses> <!--描述了項目的license,用于生成項目的web站點的license頁面,其他一些報表和validation也會用到 該元素。 --> <license> <!--license用于法律上的名稱 --> <name> Apache 2 </name> <!--官方的license正文頁面的URL --> <url>http://www.clf.com/LICENSE-2.0.txt </url> <!--項目分發(fā)的主要方式: repo,可以從Maven庫下載 manual, 用戶必須手動下載和安裝依賴 --> <distribution> repo</distribution> <!--關(guān)于license的補充信息 --> <comments> Abusiness-friendly OSS license </comments> </license> </licenses> <!--描述項目所屬組織的各種屬性。Maven產(chǎn)生的文檔用 --> <organization> <!--組織的全名 --> <name> demo </name> <!--組織主頁的URL --> <url> http://www.clf.com/</url> </organization>
還有其他很多,想要了解的可以去官網(wǎng)看看更加詳細的版本。
5、Maven依賴
Maven給我們帶來的最大的便利就是自動幫我們下載并且管理依賴,我們不必再向之前那樣自己在網(wǎng)上尋找各種依賴,導入工程中;這大大簡化了我們的開發(fā)工作,提高了效率。
接下來我們來看看maven如何解決依賴問題。
當我們在maven的pom配置文件中引入依賴后,也就是在中配置后,maven會自動幫我們下載我們所需要的依賴。
那么這個依賴是如何下載的呢?
通過上圖我們可以發(fā)現(xiàn),當maven項目導入依賴之后,首先從本地倉庫查找依賴,找不到則取遠程倉庫查找,這里去遠程倉庫就用到了我們之前配置的鏡像。
如果在公司內(nèi)部,電腦無法聯(lián)網(wǎng),那么可能查完本地會去私服查找依賴,這個私服既在局域網(wǎng)內(nèi)部,又可以連接外網(wǎng),而且在局域網(wǎng)內(nèi)部下載相當快。私服的配置一般通過nexus來完成的。
在開發(fā)過程中,我們的項目可以依賴第三方的jar包,那么第三方的jar包也可以依賴其他人的jar包,那么如果依賴重復了,maven如何解決依賴的傳遞性呢,它有如下幾種原則:
最短路徑優(yōu)先:如果A依賴B,B依賴C,而且A和B同時依賴于D,并且兩個版本不一致,那么根據(jù)最短路徑優(yōu)先原則來看,我們的項目依賴的是A依賴的D
路徑相同先聲明原則:如果我們的工程同時依賴于A和B,而且A和B都依賴D,且版本不一致,那么誰先聲明項目就依賴哪個版本的D
當我們不想要某個jar包依賴的jar包時,我們可以通過exclusions來排除jar包的依賴。
6、聚合和繼承
在項目開發(fā)過程中,我們通常使用maven構(gòu)建一個整體的項目,然后在其中構(gòu)建不同的子模塊進行開發(fā)工作,那么這些父子工程就對應了聚合和繼承。
對于聚合和繼承,有兩個關(guān)鍵的標簽,分別是parent和modules:
- parent:定義模塊的父工程,其中根據(jù)groudId和artifactId來定位父工程
- modules:描述父工程包含的子工程的名稱
可以被繼承的元素如下:
可以被繼承的POM元素如下:
- groupId:項目組ID,項目坐標的核心元素
- version:項目版本,項目坐標的核心因素
- properties:自定義的Maven屬性 一般用于同一制定各個依賴的版本號
- dependencies:項目的依賴配置 公共的依賴
- dependencyManagement:項目的依賴管理配置
- repositories:項目的倉庫配置
- build:包括項目的源碼目錄配置、輸出目錄配置、插件配置、插件管理配置等
此外還有一些項目的描述信息也可以被繼承:
- description:項目的描述信息
- organization:項目的組織信息
- inceptionYear:項目的創(chuàng)始年份
- url:項目的URL地址
- developers:項目的開發(fā)者信息
- contributors:項目的貢獻者信息
- distributionManagement:項目的部署配置
- issueManagement:項目的缺陷跟蹤系統(tǒng)信息
- ciManagement:項目的持續(xù)集成系統(tǒng)信息
- scm:項目的版本控制系統(tǒng)
- malilingLists:項目的郵件列表信息
- reporting:包括項目的報告輸出目錄配置、報告插件配置等
6.1、使用idea創(chuàng)建聚合工程
首先選擇新建maven項目:
不選擇任何模板,直接next,然后給定項目的名稱,點擊finish即可完成項目的創(chuàng)建:
項目創(chuàng)建完成后可以刪除對應的src目錄,因為我們要創(chuàng)建子模塊,不會在這個父工程中寫代碼:
然后右鍵項目名,選擇新建module:
選擇父模塊,并且填寫相關(guān)的信息:
當新建完成以后,我們看看兩個工程的pom文件:
可以看到對應的父子信息了。
6.2、使用idea創(chuàng)建分布式聚合工程
當我們創(chuàng)建分布式項目時,往往都是創(chuàng)建一個maven項目,然后在其下面創(chuàng)建不同的子模塊。這些子模塊有可能是spring boot項目,如果使用idea的Spring Initializr創(chuàng)建的話,那么默認父項目為:
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.3.1.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent>
這個默認的父項目為我們定義了各種各樣的依賴版本,我們在開發(fā)過程中可以很輕松的解決版本相關(guān)的問題。
但是這樣的話,我們統(tǒng)一創(chuàng)建的maven項目就沒有意義了,那么我們?nèi)绾谓鉀Q這個問題呢?
如果我們查看這個父工程的話,可以發(fā)現(xiàn)它的父工程為:
我們再看看spring-boot-dependencies:
其實這個spring-boot-dependencies已經(jīng)為我們定義好了各種版本依賴,那么真正解決版本問題的實際上就是spring-boot-dependencies,所以如果我們在父maven項目中依賴了spring-boot-dependencies,那么也可以進行版本的配置管理,不用擔心復雜的版本問題,所以我們可以使用如下方式新建分布式項目。
- 首先創(chuàng)建一個maven項目,并將src目錄刪除
- 在pom目錄中引入spring-boot-dependencies依賴
- 創(chuàng)建maven子項目,然后在子項目中自行引入相關(guān)的依賴即可。
這里我們使用spring-boot-dependencies進行了版本的管理。
那么對應的父工程pom文件為:
<?xml version="1.0" encoding="UTF-8"?> <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>cn.wygandwdn</groupId> <artifactId>micro_official</artifactId> <packaging>pom</packaging> <version>1.0-SNAPSHOT</version> <modules> <module>micro_official_news</module> </modules> <properties> <maven.compiler.source>8</maven.compiler.source> <maven.compiler.target>8</maven.compiler.target> <mysql-connector-java.version>8.0.22</mysql-connector-java.version> <mybatis-spring-boot-starter.version>2.1.4</mybatis-spring-boot-starter.version> <lombok.version>1.18.20</lombok.version> <spring.boot.dependencies.version>2.4.5</spring.boot.dependencies.version> <fastjson.version>1.2.47</fastjson.version> </properties> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>${spring.boot.dependencies.version}</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>${mybatis-spring-boot-starter.version}</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>${mysql-connector-java.version}</version> <scope>runtime</scope> </dependency> <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok --> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>${lombok.version}</version> <scope>provided</scope> </dependency> <!--解析json字符--> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>${fastjson.version}</version> </dependency> </dependencies> </dependencyManagement> </project>
子工程pom文件為:
<?xml version="1.0" encoding="UTF-8"?> <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 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>cn.wygandwdn</groupId> <artifactId>micro_official</artifactId> <version>1.0-SNAPSHOT</version> </parent> <!--由于我們繼承父工程,所以無需再寫groupId和version,只寫artifactId即可--> <artifactId>micro_official_news</artifactId> <name>micro_official_news</name> <description>news</description> <properties> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
7、Maven插件
Maven實際上是依賴插件執(zhí)行的框架,每個任務(wù)實際上是由插件完成的,Maven插件通常被用來:
- 打jar包
- 創(chuàng)建war包
- 編譯代碼文件
- 代碼單元測試
- 創(chuàng)建工程文檔、工程報告等
插件通常提供了一個目標的集合,并且可以使用下面的語法執(zhí)行:
mvn [plugin-name]:[goal-name]
例如,一個 Java 工程可以使用 maven-compiler-plugin 的 compile-goal 編譯,使用以下命令:
mvn compiler:compile
7.1 Spring Boot插件
<build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build>
Spring Boot的Maven插件(Spring Boot Maven plugin)能夠以Maven的方式為應用提供Spring Boot的支持,即為Spring Boot應用提供了執(zhí)行Maven操作的可能。
Spring Boot Maven plugin能夠?qū)pring Boot應用打包為可執(zhí)行的jar或war文件,然后以通常的方式運行Spring Boot應用。
Spring Boot Maven plugin的5個Goals
- spring-boot:repackage,默認goal。在mvn package之后,再次打包可執(zhí)行的jar/war,同時保留mvn package生成的jar/war為.origin
- spring-boot:run,運行Spring Boot應用
- spring-boot:start,在mvn integration-test階段,進行Spring Boot應用生命周期的管理
- spring-boot:stop,在mvn integration-test階段,進行Spring Boot應用生命周期的管理
- spring-boot:build-info,生成Actuator使用的構(gòu)建信息文件build-info.properties
8、總結(jié)
maven還有很多知識,了解了這些基本的maven知識以后,其他相關(guān)的知識也可以很快掌握。
更多有關(guān)maven的知識可以參考官網(wǎng),以上講述的知識已經(jīng)可以勝任我們?nèi)粘5拈_發(fā)工作了。
9、參考
以上就是Java開發(fā)利器Maven的詳細內(nèi)容,更多關(guān)于java開發(fā)工具maven的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
細數(shù)Java接口的概念、分類及與抽象類的區(qū)別
下面小編就為大家?guī)硪黄殧?shù)Java接口的概念、分類及與抽象類的區(qū)別。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2016-11-11Spring?Data?JPA查詢方式及方法名查詢規(guī)則介紹
這篇文章主要介紹了Spring?Data?JPA查詢方式及方法名查詢規(guī)則,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-11-11Mybatis-Plus3.x的創(chuàng)建步驟及使用教程
MyBatis-Plus是一個?MyBatis?的增強工具,在?MyBatis?的基礎(chǔ)上只做增強不做改變,為?簡化開發(fā)、提高效率而生,這篇文章主要介紹了Mybatis-Plus3.x的使用,需要的朋友可以參考下2023-10-10解決Aop @AfterReturning因返回類型不一致導致無法執(zhí)行切面代碼
這篇文章主要介紹了解決Aop @AfterReturning因返回類型不一致導致無法執(zhí)行切面代碼問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-07-07Spring?cloud?OpenFeign中動態(tài)URl、動態(tài)傳遞接口地址代碼示例
openFeign是作為微服務(wù)之間調(diào)用的解決方案,每個微服務(wù)項目是必不可少的,下面這篇文章主要給大家介紹了關(guān)于Spring?cloud?OpenFeign中動態(tài)URl、動態(tài)傳遞接口地址的相關(guān)資料,需要的朋友可以參考下2024-02-02