一、為什麼要Maven 在開發中經常需要依賴第三方的包,包與包之間存在依賴關係,版本間還有相容性問題,有時還里要將舊的包升級或降級,當項目複雜到一定程度時包管理變得非常重要。 Maven是當前最受歡迎的Java項目管理構建自動化綜合工具,類似以前Java中的Ant、node.js中的npm、dotN ...
一、為什麼要Maven
在開發中經常需要依賴第三方的包,包與包之間存在依賴關係,版本間還有相容性問題,有時還里要將舊的包升級或降級,當項目複雜到一定程度時包管理變得非常重要。
Maven是當前最受歡迎的Java項目管理構建自動化綜合工具,類似以前Java中的Ant、node.js中的npm、dotNet中的nuget、PHP中的Composer。
Maven這個單詞來自於意第緒語(猶太語),意為知識的積累。
Maven提供了開發人員構建一個完整的生命周期框架。開發團隊可以自動完成項目的基礎工具建設,Maven使用標準的目錄結構和預設構建生命周期。Maven讓開發人員的工作更輕鬆,同時創建報表,檢查,構建和測試自動化設置。Maven簡化和標準化項目建設過程。處理編譯,分配,文檔,團隊協作和其他任務的無縫連接。 Maven增加可重用性並負責建立相關的任務。
每個Java項目的目錄結構都沒有一個統一的標準,配置文件到處都是,單元測試代碼到底應該放在那裡也沒有一個權威的規範。
因此,我們就要用到Maven(使用Ant也可以,不過編寫Ant的xml腳本比較麻煩)----一個項目管理工具。
Maven主要做了兩件事:
- 統一開發規範與工具
- 統一管理jar包
如果沒有Maven,你可能不得不經歷下麵的過程:
1 如果使用了spring,去spring的官網下載jar包;如果使用hibernate,去hibernate的官網下載Jar包;如果使用Log4j,去log4j的官網下載jar包..... 2 當某些jar包有依賴的時候,還要去下載對應的依賴jar包 3 當jar包依賴有衝突時,不得不一個一個的排查 4 執行構建時,需要使用ant寫出很多重覆的任務代碼 5 當新人加入開發時,需要拷貝大量的jar包,然後重覆進行構建 6 當進行測試時,需要一個一個的運行....檢查
有了Maven,它提供了三種功能:
1 依賴的管理:僅僅通過jar包的幾個屬性,就能確定唯一的jar包,在指定的文件pom.xml中,只要寫入這些依賴屬性,就會自動下載並管理jar包。 2 項目的構建:內置很多的插件與生命周期,支持多種任務,比如校驗、編譯、測試、打包、部署、發佈... 3 項目的知識管理:管理項目相關的其他內容,比如開發者信息,版本等等
教程:https://www.yiibai.com/maven/
Maven庫:http://repo2.maven.org/maven2/
中央倉庫資源:
二、安裝與配置
其實主流的開發工具如IDEA、Eclipse都集成了Maven(可見重要性),但為了更加深刻的學習與管理該工具(比如多個IDE共用的問題),個人建議還是單獨安裝比較好。
2.1、官網下載安裝包
在瀏覽器中打開下載地址:http://maven.apache.org/download.cgi
2.2、配置環境變數
註意:安裝maven之前,必須先確保你的機器中已經安裝了JDK,如果是Maven3則必須JDK1.7以上。
1.解壓壓縮包
2.添加環境變數MAVEN_HOME,值為apache-maven的安裝路徑(沒有中文)
3.在Path環境變數的變數值末尾添加%MAVEN_HOME%\bin;
4.在cmd輸入mvn –version,如果出現maven的版本信息,說明配置成功。
2.3、本地倉儲配置
如果您不配置,預設會在如下位置存放從遠程下載到的包:
從中央倉庫下載的jar包,都會統一存放到本地倉庫中。我們需要配置本地倉庫的位置。
打開maven安裝目錄,打開conf目錄下的setting.xml文件。
可以參照下圖配置本地倉儲位置。
你還可以在運行時指定本地倉庫位置:
mvn clean install -Dmaven.repo.local=d:\yourpath
2.4、中央倉庫配置
當構建一個Maven項目時,首先檢查pom.xml文件以確定依賴包的下載位置,執行順序如下:
1、從本地資源庫中查找並獲得依賴包,如果沒有,執行第2步。 2、從Maven預設中央倉庫中查找並獲得依賴包(http://repo1.maven.org/maven2/),如果沒有,執行第3步。 3、如果在pom.xml中定義了自定義的遠程倉庫,那麼也會在這裡的倉庫中進行查找並獲得依賴包,如果都沒有找到,那麼Maven就會拋出異常。
修改預設中央倉庫地址
常用地址:
1、http://www.sonatype.org/nexus/ 私服nexus工具使用 2、http://mvnrepository.com/ (推薦) 3、http://repo1.maven.org/maven2 4、http://maven.aliyun.com/nexus/content/groups/public/ 阿裡雲 (強力推薦) 5、http://repo2.maven.org/maven2/ 私服nexus工具使用 6、http://uk.maven.org/maven2/ 7、http://repository.jboss.org/nexus/content/groups/public 8、http://maven.oschina.net/content/groups/public/ 9、http://mirrors.ibiblio.org/maven2/ 10、http://maven.antelink.com/content/repositories/central/ 11、http://nexus.openkoala.org/nexus/content/groups/Koala-release/ 12、http://maven.tmatesoft.com/content/groups/public/
完整配置文件:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<?xml version="1.0" encoding="UTF-8"?> <!-- Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --> <!-- | This is the configuration file for Maven. It can be specified at two levels: | | 1. User Level. This settings.xml file provides configuration for a single user, | and is normally provided in ${user.home}/.m2/settings.xml. | | NOTE: This location can be overridden with the CLI option: | | -s /path/to/user/settings.xml | | 2. Global Level. This settings.xml file provides configuration for all Maven | users on a machine (assuming they're all using the same Maven | installation). It's normally provided in | ${maven.home}/conf/settings.xml. | | NOTE: This location can be overridden with the CLI option: | | -gs /path/to/global/settings.xml | | The sections in this sample file are intended to give you a running start at | getting the most out of your Maven installation. Where appropriate, the default | values (values used when the setting is not specified) are provided. | |--> <settings xmlns="http://maven.apache.org/SETTINGS/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd"> <!-- localRepository | The path to the local repository maven will use to store artifacts. | | Default: ${user.home}/.m2/repository <localRepository>/path/to/local/repo</localRepository> --> <localRepository>H:\InstallFiles\javaKit\mavenRes</localRepository> <!-- interactiveMode | This will determine whether maven prompts you when it needs input. If set to false, | maven will use a sensible default value, perhaps based on some other setting, for | the parameter in question. | | Default: true <interactiveMode>true</interactiveMode> --> <!-- offline | Determines whether maven should attempt to connect to the network when executing a build. | This will have an effect on artifact downloads, artifact deployment, and others. | | Default: false <offline>false</offline> --> <!-- pluginGroups | This is a list of additional group identifiers that will be searched when resolving plugins by their prefix, i.e. | when invoking a command line like "mvn prefix:goal". Maven will automatically add the group identifiers | "org.apache.maven.plugins" and "org.codehaus.mojo" if these are not already contained in the list. |--> <pluginGroups> <!-- pluginGroup | Specifies a further group identifier to use for plugin lookup. <pluginGroup>com.your.plugins</pluginGroup> --> </pluginGroups> <!-- proxies | This is a list of proxies which can be used on this machine to connect to the network. | Unless otherwise specified (by system property or command-line switch), the first proxy | specification in this list marked as active will be used. |--> <proxies> <!-- proxy | Specification for one proxy, to be used in connecting to the network. | <proxy> <id>optional</id> <active>true</active> <protocol>http</protocol> <username>proxyuser</username> <password>proxypass</password> <host>proxy.host.net</host> <port>80</port> <nonProxyHosts>local.net|some.host.com</nonProxyHosts> </proxy> --> </proxies> <!-- servers | This is a list of authentication profiles, keyed by the server-id used within the system. | Authentication profiles can be used whenever maven must make a connection to a remote server. |--> <servers> <!-- server | Specifies the authentication information to use when connecting to a particular server, identified by | a unique name within the system (referred to by the 'id' attribute below). | | NOTE: You should either specify username/password OR privateKey/passphrase, since these pairings are | used together. | <server> <id>deploymentRepo</id> <username>repouser</username> <password>repopwd</password> </server> --> <!-- Another sample, using keys to authenticate. <server> <id>siteServer</id> <privateKey>/path/to/private/key</privateKey> <passphrase>optional; leave empty if not used.</passphrase> </server> --> <server> <id>admin</id> <username>admin</username> <password>admin</password> </server> </servers> <!-- mirrors | This is a list of mirrors to be used in downloading artifacts from remote repositories. | | It works like this: a POM may declare a repository to use in resolving certain artifacts. | However, this repository may have problems with heavy traffic at times, so people have mirrored | it to several places. | | That repository definition will have a unique id, so we can create a mirror reference for that | repository, to be used as an alternate download site. The mirror site will be the preferred | server for that repository. |--> <mirrors> <!-- mirror | Specifies a repository mirror site to use instead of a given repository. The repository that | this mirror serves has an ID that matches the mirrorOf element of this mirror. IDs are used | for inheritance and direct lookup purposes, and must be unique across the set of mirrors. | <mirror> <id>mirrorId</id> <mirrorOf>repositoryId</mirrorOf> <name>Human Readable Name for this Mirror.</name> <url>http://my.repository.com/repo/path</url> </mirror> --> <mirror> <id>nexus-aliyun</id> <mirrorOf>*,!jeecg,!jeecg-snapshots</mirrorOf> <name>Nexus aliyun</name> <url>http://maven.aliyun.com/nexus/content/groups/public</url> </mirror> </mirrors> <!-- profiles | This is a list of profiles which can be activated in a variety of ways, and which can modify | the build process. Profiles provided in the settings.xml are intended to provide local machine- | specific paths and repository locations which allow the build to work in the local environment. | | For example, if you have an integration testing plugin - like cactus - that needs to know where | your Tomcat instance is installed, you can provide a variable here such that the variable is | dereferenced during the build process to configure the cactus plugin. | | As noted above, profiles can be activated in a variety of ways. One way - the activeProfiles | section of this document (settings.xml) - will be discussed later. Another way essentially | relies on the detection of a system property, either matching a particular value for the property, | or merely testing its existence. Profiles can also be activated by JDK version prefix, where a | value of '1.4' might activate a profile when the build is executed on a JDK version of '1.4.2_07'. | Finally, the list of active profiles can be specified directly from the command line. | | NOTE: For profiles defined in the settings.xml, you are restricted to specifying only artifact | repositories, plugin repositories, and free-form properties to be used as configuration | variables for plugins in the POM. | |--> <profiles> <!-- profile | Specifies a set of introductions to the build process, to be activated using one or more of the | mechanisms described above. For inheritance purposes, and to activate profiles via <activatedProfiles/> | or the command line, profiles have to have an ID that is unique. | | An encouraged best practice for profile identification is to use a consistent naming convention | for profiles, such as 'env-dev', 'env-test', 'env-production', 'user-jdcasey', 'user-brett', etc. | This will make it more intuitive to understand what the set of introduced profiles is attempting | to accomplish, particularly when you only have a list of profile id's for debug. | | This profile example uses the JDK version to trigger activation, and provides a JDK-specific repo. <profile> <id>jdk-1.4</id> <activation> <jdk>1.4</jdk> </activation> <repositories> <repository> <id>jdk14</id> <name>Repository for JDK 1.4 builds</name> <url>http://www.myhost.com/maven/jdk14</url> <layout>default</layout> <snapshotPolicy>always</snapshotPolicy> </repository> </repositories> </profile> --> <!-- | Here is another profile, activated by the system property 'target-env' with a value of 'dev', | which provides a specific path to the Tomcat instance. To use this, your plugin configuration | might hypothetically look like: | | ... | <plugin> | <groupId>org.myco.myplugins</groupId> | <artifactId>myplugin</artifactId> | | <configuration> | <tomcatLocation>${tomcatPath}</tomcatLocation> | </configuration> | </plugin> | ... | | NOTE: If you just wanted to inject this configuration whenever someone set 'target-env' to | anything, you could just leave off the <value/> inside the activation-property. | <profile> <id>env-dev</id> <activation> <property> <name>target-env</name> <value>dev</value> </property> </activation> <properties> <tomcatPath>/path/to/tomcat/instance</tomcatPath> </properties> </profile> --> <profile> <id>jdk1.7</id> <activation> <activeByDefault>true</activeByDefault> <jdk>1.7</jdk> </activation> <properties> <maven.compiler.source>1.7</maven.compiler.source> <maven.compiler.target>1.7</maven.compiler.target> <maven.compiler.compilerVersion>1.7</maven.compiler.compilerVersion> </properties> </profile> </profiles> <!-- activeProfiles | List of profiles that are active for all builds. | <activeProfiles> <activeProfile>alwaysActiveProfile</activeProfile> <activeProfile>anotherAlwaysActiveProfile</activeProfile> </activeProfiles> --> </settings>View Code
2.5、命令行創建maven項目
方法一:
輸入命令 mvn archetype:generate,按回車,根據提示輸入參數,如果是第一次使用,需要下載插件,稍等幾分鐘即可。
切換目錄,輸入指令
選擇骨架(模板):
輸入座標:
確認後下載骨架,成功後的提示如下:
將項目轉換成IDEA項目:
成功後可以看到增加了項目信息:
在IDEA中就可以直接打開項目了:
將項目打包
輸入指令:mvn package
打包成功後:
方法二:
在命令中指定參數
mvn archetype:generate -DgroupId=com.mycompany.app -DartifactId=myapp -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
執行結果:
在命令行輸入:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
mvn archetype:generate -DgroupId=com.zhangguo.mvntest04 -DartifactId=MvnTest04 -DarchetypeArtifactId=maven-archetype-webapp -DinteractiveMode=false
View Code
在命令行輸入指令時請註意當前目錄:
成功提示:
新建一個簡單web項目
mvn archetype:generate -DgroupId=com.zhangguo -DartifactId=webappdemo -Dpackage=com.zhangguo.webappdemo -DarchetypeArtifactId=maven-archetype-webapp -Dversion=1.0 -DinteractiveMode=No
如果下載骨架的速度太慢,可以用-DarchetypeCatalog=指定下載位置,如下所示:
mvn archetype:generate \ -DgroupId=com.mycom.helloworld \ -DartifactId=helloworld \ -DarchetypeArtifactId=maven-archetype-quickstart \ -DinteractiveMode=false \ -DarchetypeCatalog=http://maven.aliyun.com/nexus/content/groups/public/
更多解決方法:https://www.cnblogs.com/del88/p/6286887.html
2.6、Jetty運行Web項目
是一個開源的servlet容器,它為基於Java的web容器,例如JSP和servlet提供運行環境。Jetty是使用Java語言編寫的,它的API以一組JAR包的形式發佈。開發人員可以將Jetty容器實例化成一個對象,可以迅速為一些獨立運行(stand-alone)的Java應用提供網路和web連接。
官網:http://www.eclipse.org/jetty/
jetty的特點:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
//易用性 易用性是 Jetty 設計的基本原則,易用性主要體現在以下幾個方面: 通過 XML 或者 API 來對Jetty進行配置;預設配置可以滿足大部分的需求;將 Jetty 嵌入到應用程式當中只需要非常少的代碼; //可擴展性 在使用了 Ajax 的 Web 2.0 的應用程式中,每個連接需要保持更長的時間,這樣線程和記憶體的消耗量會急劇的增加。這就使得我們擔心整個程式會因為單個組件陷入瓶頸而影響整個程式的性能。但是有了 Jetty: 即使在有大量服務請求的情況下,系統的性能也能保持在一個可以接受的狀態。利用 Continuation 機制來處理大量的用戶請求以及時間比較長的連接。 另外 Jetty 設計了非常良好的介面,因此在 Jetty 的某種實現無法滿足用戶的需要時,用戶可以非常方便地對 Jetty 的某些實現進行修改,使得 Jetty 適用於特殊的應用程式的需求。 //易嵌入性 Jetty 設計之初就是作為一個優秀的組件來設計的,這也就意味著 Jetty 可以非常容易的嵌入到應用程式當中而不需要程式為了使用 Jetty 做修改。從某種程度上,你也可以把 Jetty 理解為一個嵌入式的Web伺服器。 Jetty 可以作為嵌入式伺服器使用,Jetty的運行速度較快,而且是輕量級的,可以在Java中可以從test case中控制其運行。從而可以使自動化測試不再依賴外部環境,順利實現自動化測試。View Code
maven項目直接在jetty中運行
2.6.1、修改pom,增加jetty插件:
<plugins> <!-- jetty插件 --> <plugin> <groupId>org.mortbay.jetty</groupId> <artifactId>maven-jetty-plugin</artifactId> <version>6.1.26</version> <configuration> <webAppSourceDirectory>src/main/webapp</webAppSourceDirectory> <scanIntervalSeconds>3</scanIntervalSeconds> <contextPath>/jetty</contextPath> <connectors> <connector implementation="org.mortbay.jetty.nio.SelectChannelConnector"> <port>4000</port> </connector> </connectors> </configuration> </plugin> </plugins>
2.6.2、將項目部署到jetty中運行:
mvn jetty:run //運行項目於jetty上,
2.6.3、在瀏覽器中輸入訪問地址:
http://127.00.0.1:4000/jetty
結束運行使用ctrl+c
2.6.4、idea中使用maven方式使用jetty
配置好後可直接點擊idea中右邊的maven選項卡,在plugins下有jetty選項,展開隨便點那個都可以啟動jetty,啟動好後就可以在瀏覽器中輸入地址訪問web應用了。
2.7、在tomcat中運行
添加插件:
<plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>tomcat-maven-plugin</artifactId> <version>1.1</version> <configuration> <path>/wp</path> <port>8080</port> <uriEncoding>UTF-8</uriEncoding> <url>http://localhost:8080/manager/html</url> <server>tomcat6</server> </configuration> </plugin>
執行命令:
tomcat:deploy --部署一個web war包 tomcat:reload --重新載入web war包 tomcat:start --啟動tomcat tomcat:stop --停止tomcat tomcat:undeploy--停止一個war包 tomcat:run 啟動嵌入式tomcat ,並運行當前項目
三、Maven概要
Maven 是一個Java項目管理工具,主要功能是統一開發規範與包的依賴管理。
3.1、Maven名詞解釋
1. POM(Project Object Model)項目對象模型
Maven項目對象模型(POM),可以通過一小段描述信息來管理項目的構建,報告和文檔的軟體項目管理工具。
POM 與 Java 代碼實現瞭解耦,當需要升級版本時,只需要修改POM,而不需要更改Java代碼,而在POM穩定後,日常的Java代碼開發基本不涉及POM的修改。
2. 坐標
groupId , artifactId , version 三個元素是項目的坐標,唯一的標識這個項目。
groupId 項目所在組,一般是組織或公司
artifactId 是當前項目在組中的唯一ID;
version 表示版本,SNAPSHOT表示快照,表示此項目還在開發中,不穩定。
groupId 和實際項目不一定是一一對應的,maven 有模塊的概念,例如 spring-core, spring-context...;groupId 也不應該只對應公司或組織名,建議具體到項目名,因為公司或者組織下有多個項目,而artifactId只能代表模塊名。
<dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <scope>test</scope> </dependency>
3.依賴範圍
1. compile : 編譯,測試,運行都有效,預設的選擇
2. test : 測試有效,例如junit
3. provided : 編譯,測試有效,例如 servlet ,運行時容器會提供實現
4. runtime : 運行和測試有效,例如 jdbc,編譯時只需相應的介面,測試和運行時才需要具體的實現
5. system : 編譯,測試有效。使用此範圍的依賴必須通過systemPath元素顯式的指定依賴文件,因而
此類依賴是不通過Maven倉庫解析的,一般適合於本機測試環境下,依賴本地起的服務。
構建
maven支持許多種的應用程式類型,對於每一種支持的應用程式類型都定義好了一組構建規則和工具集。
輸出管理
maven可以管理項目構建的產物,並將其加入到用戶庫中。這個功能可以用於項目組和其他部門之間的交付行為
依賴關係
maven對依賴關係的特性進行細緻的分析和劃分,避免開發過程中的依賴混亂和相互污染行為
文檔和構建結果
maven的site命令支持各種文檔信息的發佈,包括構建過程的各種輸出,javadoc,產品文檔等。
項目關係
一個大型的項目通常有幾個小項目或者模塊組成,用maven可以很方便地管理
移植性管理
maven可以針對不同的開發場景,輸出不同種類的輸出結果
- Project: 項目
- 任何你想 build 的事物,Maven都會把它們當作是一個 Project。
- 這些 Project 被定義為 POM(Project Object Model)。
- 一個 Project 可以依賴其他的project,一個 project 也可以有多個子project組成。
POM:文檔對象模型
- POM(pom.xml) 是 Maven 的核心文件,它是指示 Maven 如何工作的元數據文件,類似 ant 的 build.xml 文件。
- pom.xml 文件應該位於每個 Project 的根目錄。
- 顧名思義,這個應該是公司名或組織名。
- ArtifactId:項目名
- 構建出來的文件名,一般來說或,這個也是project名。
- Packaging:打包
- 項目打包的類型,可以是將jar、war、rar、ear、pom,預設是jar。
- Version:版本
- 項目的版本,項目的唯一標識由 groupId+artifactId+packaging+versionz 組成。
- Dependency: 依賴
- 為了能夠 build 或運行,一個典型的java project會依賴其他的包,在Maven中,這些被依賴的包就被稱為 dependency。
- Plug-in:插件
- Maven是有插件組織的,它的每一個功能都是由插件提供的,主要的插件是由 java 來寫的,但是他也支持 beanshell 和 ant 腳本編寫的插件。
- Repository:倉庫
- 倉庫用來存放artifact的,可以是本地倉庫,也可以是遠程倉庫,Maven是由一個預設的倉庫
- Snapshot:快照
- 工程中可以(也應該)有這樣一個特殊的版本:這個版本可以告訴Maven,該工程正在處於開發階段,會經常更新(但還為發佈)。當其他工程依賴此類型的artifact時,Maven會在倉庫中尋找該artifact的最新版本,並自動下載、使用該最新版本。
3.2、Maven的生命周期
maven把項目的構建劃分為不同的生命周期(lifecycle)。粗略一點的話,它這個過程(phase)包括:編譯、測試、打包、集成測試、驗證、部署。maven中所有的執行動作(goal)都需要指明自己在這個過程中的執行位置,然後maven執行的時候,就依照過程的發展依次調用這些goal進行各種處理。
這個也是maven的一個基本調度機制。一般來說,位置稍後的過程都會依賴於之前的過程。當然,maven同樣提供了配置文件,可以依照用戶要求,跳過某些階段。
三種生命周期
- Clean Lifecycle 在進行真正的構建之前進行一些清理工作。
- Default Lifecycle 構建的核心部分,編譯,測試,打包,部署等等。
- Site Lifecycle 生成項目報告,站點,發佈站點。
下麵列出了default、clean和site生命周期的所有構建階段,這些階段按照指定的順序執行。
clean生命周期