在項目中Maven用的一直比較多,以前只知道簡單的配置一些依賴,所以找了時間 孔浩老師 Maven的學習視頻學習了一下 Maven初步 手動建立 Maven 項目 1、新建一個簡單 項目 手動 項目:按照 規範建立項目路徑和 2、常用的Maven 命令 3、maven 預設的中央倉庫的地址 在 中 ...
在項目中Maven用的一直比較多,以前只知道簡單的配置一些依賴,所以找了時間孔浩老師Maven的學習視頻學習了一下
Maven初步-手動建立 Maven 項目
- 1、新建一個簡單
Maven
項目- 手動
Maven
項目:按照Maven
規範建立項目路徑和pom.xml
- 手動
1、示例
maven-ch01/pom.xml
maven-ch01/src/main/java/......
maven-ch01/src/main/resources/...
maven-ch01/src/test/java/......
maven-ch01/src/test/resources/...
pom.xml
<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 這是固定值不用修改 -->
<modelVersion>4.0.0</modelVersion>
<!-- GAV 模塊唯一的坐標,groupId 一般表示項目 -->
<groupId>org.panpan.hellomaven</groupId>
<!--模塊名稱 -->
<artifactId>maven-ch01</artifactId>
<!-- 版本號 -->
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<!-- 這裡放的是依賴的模塊 -->
</dependencies>
</project>
- 2、常用的Maven 命令
mvn compile //編譯
mvn test //測試
mvn package //打包
mvn install //安裝到本地倉庫
mvn deploy //發佈到倉庫中
- 3、maven 預設的中央倉庫的地址
- 在
apache-maven-3.3.9\lib\maven-model-builder-3.3.9.jar\org\apache\maven\model\pom-4.0.0.xml
中
- 在
- 4、通過 Maven 自有的固定模式生成 maven 項目
- 由於maven有一些固定的生成模式,所以使用
mvn archetype:generate
可以自動完成這個骨架的建立 - 隨後按照命令的指示建立好 maven 項目
- 當然我們也可以在命令中就設定好相關的參數:
mvn archetype:generate -DgroupId=<groupId> -DartifactId=<artifactId> -Dversion=<version>
- 由於maven有一些固定的生成模式,所以使用
Eclipse 建立 Maven 項目
- 1、在Eclipse中建立 Maven 項目
- 普通的Java項目選擇
maven-archetype-quickstart 1.1
- 輸入相關的 GAV 就可以快速建立Maven 項目
- 項目 resources 需要自己建立
- 普通的Java項目選擇
- 小技巧:
Maven
骨架快速生成配置- Eclipse 或者 IDEA建立Mavan 項目時,有時候會一直處於run狀態,只需要新增一個配置就可以:
Maven -> Runner -> VM Options : -DarchetypeCatalog=internal
- Eclipse 或者 IDEA建立Mavan 項目時,有時候會一直處於run狀態,只需要新增一個配置就可以:
Maven 中的依賴特性
- 1、當存在多個模塊開發時,項目之間就會存在依賴特性
- 示例:
- 存在三個模塊: user-core、user-log、user-service
- user-service 依賴於 user-core 和 user-log
- 示例:
- 2、依賴的傳遞性
- 在模塊之間互相依賴之後,可能存在包之間的傳遞性
- 依賴之間的傳遞範圍是基於
<scrop>compile</scrop>
,對於依賴的傳遞而言,主要是針對compile
作用域傳遞,其他的作用域並不會傳遞
- 3、傳遞的衝突問題
- 例1-相同路徑深度:
a-->b(1.0V)
c-->b(1.1V)
d-->a和c
,這個時候在 d模塊 的pom中,哪一個依賴先寫就使用先寫依賴的版本。- 對於相同路徑深度的模塊中的包依賴,那個模塊寫在pom依賴前,就依賴哪個版本
- 例2-不同路徑深度依賴
a-->b(1.0V)
c-->b(1.1V)
d-->a
和c-->b(1.0V)
f-->d和c
,如果路徑的長短不一致就選擇最小路徑f-->b1.1
- 精確控制依賴衝突問題:如果希望精確的控制依賴包,可以使用依賴的排除功能進行控制
- 例1-相同路徑深度:
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>user-log</artifactId>
<version>0.0.1-SNAPSHOT</version>
<!-- 排重 user-log 模塊中的 commoms-logging 依賴 -->
<exclusions>
<exclusion>
<groupId>commoms-logging</groupId>
<artifactId>commoms-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
Maven 依賴範圍
- 1、
test
範圍指的是測試範圍有效,在編譯和打包時都不會使用這個依賴 - 2、
compile
範圍指的是編譯範圍有效,在編譯和打包時都會將依賴存儲進去 - 3、
provided
依賴:在編譯和測試的過程有效,最後生成war包時不會加入,諸如: servlet-api,因為servlet-api,tomcat等web伺服器已經存在了,如果再打包會衝突 - 4、
runtime
在運行的時候依賴,在編譯的時候不依賴 - 5、預設的依賴範圍是
compile
, 也只有compile
範圍才能進行依賴傳遞
<!-- 測試範圍的依賴 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!-- 運行的時候依賴 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.38</version>
<scope>runtime</scope>
</dependency>
Maven的聚合和繼承
- 1、Maven 聚合
- 在maven 模塊中,如果一個項目每個模塊都去單獨的操作這樣會很不方便,重覆操作太多所以我們可以使用聚合的方法來進行 maven 項目的統一操作
- 在之前三個模塊的根目錄下新建一個空白的 maven 項目,主要用於管理這三個
maven
項目,並且pom.xml
需要按照下麵例子來建立。
示例: 聚合和繼承的路徑
user-maven/pom.xml
user-maven/user-core
user-maven/user-log
user-maven/user-service
<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>org.panpan.hellomaven</groupId>
<artifactId>user-maven</artifactId>
<version>0.0.1-SNAPSHOT</version>
<!-- 類型為pom 管理 -->
<packaging>pom</packaging>
<!-- module 聚合裡面存放是項目模塊的絕對路徑 -->
<modules>
<module>user-dao</module>
<module>user-log</module>
<module>user-service</module>
</modules>
</project>
- 2、
Maven
的繼承- 在 Maven 的每個模塊項目中,一些包依賴需要重覆的去添加,所以我們可以採用在一個頂級的
pom.xml
來統一管理這些模塊和包之間的依賴 - 通常我們會把 聚合 和 繼承統一在一個
pom.xml
文件中
- 在 Maven 的每個模塊項目中,一些包依賴需要重覆的去添加,所以我們可以採用在一個頂級的
user-maven 中的 pom.xml 配置
<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>org.panpan.hellomaven</groupId>
<artifactId>user-maven</artifactId>
<version>0.0.1-SNAPSHOT</version>
<!-- 類型為pom 管理 -->
<packaging>pom</packaging>
<url>http://maven.apache.org</url>
<!-- module 聚合裡面存放是項目模塊的絕對路徑 -->
<modules>
<module>user-dao</module>
<module>user-log</module>
<module>user-service</module>
</modules>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<junit.version>4.12</junit.version>
<lombok.version>1.16.10</lombok.version>
<log4j.version>1.2.17</log4j.version>
<slf4j.version>1.5.2</slf4j.version>
<dbunit.version>2.4.5</dbunit.version>
<mysql.version>5.1.38</mysql.version>
<hibernate.version>4.3.11.Final</hibernate.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.dbunit</groupId>
<artifactId>dbunit</artifactId>
<version>${dbunit.version}</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>${hibernate.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
</project>
在user-dao 中繼承 user-maven 的 pom.xml 文件
<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>
<!-- 繼承user-maven 的pomx.ml -->
<parent>
<groupId>org.panpan.hellomaven</groupId>
<artifactId>user-maven</artifactId>
<version>0.0.1-SNAPSHOT</version>
<!-- 繼承的絕對路徑是pom的文件, 如果是在外層可以不添加這個配置 -->
<!-- 或預設繼承在該模塊的最外層根目錄下 -->
<relativePath>../pom.xml</relativePath>
</parent>
<groupId>org.panpan.hellomaven</groupId>
<artifactId>user-dao</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>user-dao</name>
<dependencies>
<!-- 對於繼承過來的,可以不用寫上版本號繼承 user-maven -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</dependency>
<dependency>
<groupId>org.dbunit</groupId>
<artifactId>dbunit</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
</dependency>
</dependencies>
</project>
Nexus repository
nexus 介紹和安裝
- 1、Nexus 介紹
* Nexus 是Maven倉庫管理器,如果你使用Maven,你可以從Maven中央倉庫 下載所需要的構件(artifact),但這通常不是一個好的做法,你應該在本地架設一個Maven倉庫伺服器,在代理遠程倉庫的同時維護本地倉庫,以節省帶寬和時間,Nexus就可以滿足這樣的需要。此外,他還提供了強大的倉庫管理功能,構件搜索功能,它基於REST,友好的UI是一個extjs的REST客戶端,它占用較少的記憶體,基於簡單文件系統而非資料庫。這些優點使其日趨成為最流行的Maven倉庫管理器。 - 2、Nexus 安裝
- 你可以從http://nexus.sonatype.org/downloads/ 下載最新版本的Nexus,Nexus提供了兩種安裝方式,一種是內嵌Jetty的bundle,只要你有JRE就能直接運行。第二種方式是WAR,你只須簡單的將其發佈到web容器中即可使用。
- Bundle方式安裝
- 解壓nexus-webapp-1.3.0-bundle.zip 至任意目錄,如D:\dev_tools ,然後打開CMD,cd至目錄D:\dev_tools\nexus-webapp-1.3.0\bin\jsw\windows-x86-32 ,運行Nexus.bat 。你會看到Nexus的啟動日誌,當你看到“Started [email protected]:8081”之後,說明Nexus啟動成功了,然後打開瀏覽器,訪問http://127.0.0.1:8081/nexus
- 要停止Nexus,Ctrl+C即可,此外InstallNexus.bat可以用來將Nexus安裝成一個windows服務,其餘的腳本則對應了啟動,停止,暫停,恢復,卸載Nexus服務。
- WAR方式安裝
- 你需要有一個能運行的web容器,這裡以Tomcat為例,加入Tomcat的安裝目錄位於D:\DevInstall\apache-tomcat-7.0.9,首先我們將下載的nexus-webapp-xxx.war 重命名為nexus.war ,然後複製到D:\DevInstall\apache-tomcat-7.0.9\webapps\nexus.war ,然後啟動CMD,cd到D:\DevInstall\apache-tomcat-7.0.9\bin\ 目錄,運行startup.bat 。一切OK,現在可以打開瀏覽器訪問http://127.0.0.1:8080/nexus,你會得到和上圖一樣的界面。
nexus的配置
- 預設情況下,Maven依賴於中央倉庫,這是為了能讓Maven開箱即用,但僅僅這麼做明顯是錯誤的,這會造成大量的時間及帶寬的浪費。既然文章的前面已經介紹瞭如何安裝和配置Nexus,現在我們就要配置Maven來使用本地的Nexus,以節省時間和帶寬資源。
- 我們可以將Repository配置到POM中,但一般來說這不是很好的做法,原因很簡單,你需要為所有的Maven項目重覆該配置。因此,這裡我將Repository的配置放到
settings.xml
中:
<profiles>
<profile>
<id>nexusProfile</id>
<repositories>
<repository>
<id>nexus</id>
<name>Nexus Repository</name>
<url>http://127.0.0.1:8080/nexus/content/groups/public/</url>
<!-- 可以下載releases Jar 包 預設是true -->
<releases>
<enabled>true</enabled>
</releases>
<!-- 可以下載snapshots Jar包預設是false -->
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
</profile>
</profiles>
<!-- 在這激活哪個profile id,哪個就生效 -->
<activeProfiles>
<activeProfile>nexusProfile</activeProfile>
</activeProfiles>
- 當然,我們還可以配置工廠的鏡像,那設置工廠的查找範圍。例如只能在本地伺服器的工廠中查詢
<mirrors>
<!-- 工廠的鏡像,只要mirrorOf 中的工廠要訪問,都會自動來找鏡像,就不會再去重要工廠 -->
<mirror>
<!--This sends everything else to /public -->
<id>nexus</id>
<!-- 也可以配置為 * 來代替-->
<mirrorOf>nexus,central</mirrorOf>
<url>http://192.168.0.221:8081/nexus/content/groups/public</url>
</mirror>
</mirrors>
- 在配置了工廠鏡像之後,在之前的
nexusProfile
的配置就沒有必要配置了,但是對於想要能夠依賴中央工廠中的snapshots
版本的鏡像,我們可以採用覆蓋maven中的預設配置方式
<profiles>
<profile>
<id>nexus</id>
<!--Enable snapshots for the built in central repo to direct -->
<!--all requests to nexus via the mirror -->
<repositories>
<!-- 表示配置中央工廠中的snapshots為true,查找地址為上面配置mirror 鏡像 -->
<repository>
<id>central</id>
<url>http://central</url>
<releases><enabled>true</enabled></releases>
<snapshots><enabled>true</enabled></snapshots>
</repository>
</repositories>
</profile>
</profiles>
<activeProfiles>
<!--make the profile active all the time -->
<activeProfile>nexus</activeProfile>
</activeProfiles>
發佈項目到nexus
中
- 更常見的用例是:團隊在開發一個項目的各個模塊,為了讓自己開發的模塊能夠快速讓其他人使用,你會想要將snapshot版本的構件部署到Maven倉庫中,其他人只需要在POM添加一個對於你開發模塊的依賴,就能隨時拿到最新的snapshot。
- 以下的
pom.xml
配置和settings.xml
能讓你通過Maven自動化部署構件:
<!-- pom.xml -->
<!-- 只要在parent 模塊中配置,後面模塊都繼承就行 -->
<distributionManagement>
<repository>
<id>nexus-releases</id>
<name>Nexus Release Repository</name>
<url>http://127.0.0.1:8080/nexus/content/repositories/releases/</url>
</repository>
<snapshotRepository>
<id>nexus-snapshots</id>
<name>Nexus Snapshot Repository</name>
<url>http://127.0.0.1:8080/nexus/content/repositories/snapshots/</url>
</snapshotRepository>
</distributionManagement>
<!-- setting.xml -->
<servers>
<server>
<id>nexus-releases</id>
<username>admin</username>
<password>admin123</password>
</server>
<server>
<id>nexus-snapshots</id>
<username>admin</username>
<password>admin123</password>
</server>
</servers>
生命周期和插件
maven 的三套生命周期
- 1、
clean
生命周期 pre-clean
執行一些需要在clean之前完成的工作clean
移除所有上一次構建生成的文件post-clean
執行一些需要在clean之後立刻完成的工作2、
compile
生命周期
validate
generate-sources
process-sources
generate-resources
process-resources 複製並處理資源文件,至目標目錄,準備打包。
compile 編譯項目的源代碼。 //到這一步完成 compile
process-classes
generate-test-sources
process-test-sources
generate-test-resources
process-test-resources 複製並處理資源文件,至目標測試目錄。
test-compile 編譯測試源代碼。
process-test-classes
test 使用合適的單元測試框架運行測試。這些測試代碼不會被打包或部署。
prepare-package
package 接受編譯好的代碼,打包成可發佈的格式,如 JAR 。
pre-integration-test
integration-test
post-integration-test
verify
install 將包安裝至本地倉庫,以讓其它項目依賴。
deploy 將最終的包複製到遠程的倉庫,以讓其它開發人員與項目共用。
- 3、
site
生命周期pre-site
執行一些需要在生成站點文檔之前完成的工作site
生成項目的站點文檔post-site
執行一些需要在生成站點文檔之後完成的工作,並且為部署做準備site-deploy
將生成的站點文檔部署到特定的伺服器上
Maven 插件
Maven 插件介紹
- Maven的核心是它的生命周期,生命周期什麼都不做,因此Maven的安裝文件很小。所有的事情都交給了插件來完成。比如說,Maven 的default生命周期中定義了一個compile階段,這個定義本身什麼都不會做,真正編譯代碼的是Compiler插件,它的groupId是org.apache.maven.plugins,artifactId是maven-compiler-plugin。
- 插件是 maven 的核心,所有執行的操作都是基於插件來完成的
- 為了讓一個插件中可以實現眾多的類似功能,maven為插件設定了目標,一個插件中有可能有多個目標
- 其實生命周期中的重要的每個階段都是由插件的一個具體目標來執行的
Maven 插件基礎
phase
: 可以在插件上指定聲明周期的哪一步後面執行這個插件executions
-execution
: 執行什麼操作goals
-goal
: 在綁定phase
之後,需要指定插件執行的目標,可以執行多個configuration
: 配置插件中類的註解參數,這樣可以給插件註明一些參數的值
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java_source_version>1.8</java_source_version>
<java_target_version>1.8</java_target_version>
<maven_compiler_plugin_version>3.3</maven_compiler_plugin_version>
<maven_source_plugin_version>2.4</maven_source_plugin_version>
<maven_jar_plugin_version>2.5</maven_jar_plugin_version>
<maven_war_plugin_version>2.5</maven_war_plugin_version>
<maven_deploy_plugin_version>2.8.2</maven_deploy_plugin_version>
<spring.version>4.2.1.RELEASE</spring.version>
</properties>
<build>
<plugins>
......
<!--示例—1: 指定編譯的JDK 版本號 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven_compiler_plugin_version}</version>
<configuration>
<source>${java_source_version}</source>
<target>${java_target_version}</target>
<encoding>${project.build.sourceEncoding}</encoding>
</configuration>
</plugin>
<!--示例-2:生成的Java源文件的Jar包 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>${maven_source_plugin_version}</version>
<executions>
<execution>
<id>attach-sources</id>
<!-- 指定插件的目標 -->
<goals>
<goal>jar-no-fork</goal>
</goals>
</execution>
</executions>
<configuration>
<attach>true</attach>
</configuration>
</plugin>
<!-- 示例-3: 生成Maven War包-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>${maven_war_plugin_version}</version>
<configuration>
<archive>
<addMavenDescriptor>true</addMavenDescriptor>
</archive>
</configuration>
</plugin>
<!-- 示例-4: Build a JAR from the current project. -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>${maven_jar_plugin_version}</version>
<configuration>
<archive>
<addMavenDescriptor>true</addMavenDescriptor>
</archive>
</configuration>
</plugin>
......
</plugins>
</build>