一、為什么要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/
完整配置文件:
<?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>
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
執行結果:
在命令行輸入:
mvn archetype:generate -DgroupId=com.zhangguo.mvntest04 -DartifactId=MvnTest04 -DarchetypeArtifactId=maven-archetype-webapp -DinteractiveMode=false
在命令行輸入指令時請注意當前目錄:

成功提示:

新建一個簡單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的特點:
//易用性 易用性是 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中控制其運行。從而可以使自動化測試不再依賴外部環境,順利實現自動化測試。
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生命周期
| 執行階段 | 描述說明 |
|---|---|
| pre-clean | 在實際的項目清理之前執行所需的過程 |
| clean | 刪除前一個構建生成的所有文件 |
| post-clean | 執行完成項目清理所需的過程 |
Default生命周期
| 執行階段 | 描述說明 |
|---|---|
| validate | 驗證項目是正確的,所有必要的信息都是可用的。 |
| initialize | 初始化構建狀態,例如設置屬性或創建目錄。 |
| generate-sources | 生成包含在編譯中的任何源代碼。 |
| process-sources | 處理源代碼,例如過濾任何值。 |
| generate-resources | 生成包含在包中的資源。 |
| process-resources | 將資源復制並處理到目標目錄中,准備打包。 |
| compile | 編譯項目的源代碼。 |
| process-classes | 從編譯后生成生成的文件,例如在Java類上執行字節碼增強。 |
| generate-test-sources | 生成包含在編譯中的任何測試源代碼。 |
| process-test-sources | 處理測試源代碼,例如過濾任何值。 |
| generate-test-resources | 為測試創建資源。 |
| process-test-resources | 將資源復制並處理到測試目標目錄中。 |
| test-compile | 將測試源代碼編譯到測試目標目錄 |
| process-test-classes | 從測試編譯后post-process生成文件,例如在Java類上執行字節碼增強。對於Maven 2.0.5和以上。 |
| test | 使用合適的單元測試框架運行測試。這些測試不應該要求打包或部署代碼。 |
| prepare-package | 在實際包裝前執行必要的准備工作。這通常會導致包的一個未打包的、經過處理的版本。(Maven 2.1及以上) |
| package | 使用已編譯的代碼,並將其打包成可部署格式,例如JAR。 |
| pre-integration-test | 執行集成測試之前需要執行的操作。這可能涉及到設置所需的環境等問題。 |
| integration-test | 在需要集成測試的環境中,處理並部署包。 |
| post-integration-test | 執行集成測試后所需要的操作。這可能包括清理環境。 |
| verify | 運行任何檢查以驗證包是否有效,並滿足質量標准。 |
| install | 將該包安裝到本地存儲庫中,作為本地其他項目的依賴項。 |
| deploy | 在集成或發布環境中完成,將最終包復制到遠程存儲庫中,以便與其他開發人員和項目共享。 |
Site生命周期
| 執行階段 | 描述說明 |
|---|---|
| pre-site | 在實際的項目站點生成之前執行過程 |
| site | 生成項目的站點文檔 |
| post-site | 執行確定站點生成的過程,並為站點部署做好准備 |
| site-deploy | 將生成的站點文檔部署到指定的web服務器 |
注意:執行某個生命周期的某個階段不會影響其它的生命周期!
如果要同時執行多個生命周期的階段可在命令行輸入多個命令,中間以空格隔開,例如: clean package 該命令執行clean生命周期的clean階段和default生命周期的package階段。
3.3、Maven標准工程結構
Maven的標准工程結構如下:

3.4、Maven的"約束優於配置"
所謂的"約束優於配置",在maven中並不是完全不可以修改的,他們只是一些配置的默認值而已。但是除非必要,並不需要去修改那些約定內容。maven默認的文件存放結構如1.3所示。
每一個階段的任務都知道怎么正確完成自己的工作,比如compile任務就知道從src/main/java下編譯所有的java文件,並把它的輸出class文件存放到target/classes中。
對maven來說,采用"約定優於配置"的策略可以減少修改配置的工作量,也可以降低學習成本,更重要的是,給項目引入了統一的規范。
3.5、Maven的版本規范
maven有自己的版本規范,一般是如下定義 <major version>.<minor version>.<incremental version>-<qualifier> ,比如1.2.3-beta-01。要說明的是,maven自己判斷版本的算法是major,minor,incremental部分用數字比較,qualifier部分用字符串比較,所以要小心 alpha-2和alpha-15的比較關系,最好用 alpha-02的格式。
maven在版本管理時候可以使用幾個特殊的字符串 SNAPSHOT,LATEST,RELEASE。比如"1.0-SNAPSHOT"。各個部分的含義和處理邏輯如下說明:
SNAPSHOT
這個版本一般用於開發過程中,表示不穩定的版本。
LATEST
指某個特定構件的最新發布,這個發布可能是一個發布版,也可能是一個snapshot版,具體看哪個時間最后。
RELEASE
是指倉庫中最后的一個非快照版本
規范:
1、同一項目中所有模塊版本保持一致
2、子模塊統一繼承父模塊的版本
3、統一在頂層模塊Pom的<dependencyManagement/>節中定義所有子模塊的依賴版本號,子模塊中添加依賴時不要添加版本號
4、開發測試階段使用SNAPSHOT
5、生產發布使用RELEASE
6、新版本迭代只修改頂層POM中的版本
3.6、項目骨架Maven Archetype
什么是Maven Archetype? 簡單的說就是一個Maven項目的基礎模板,利用這個模板我們就可快速的建立一個新的該類型項目,同時也可以建立自己的項目骨架。
Maven所提供的archetype功能都是由插件Maven Archetype Plugin完成的
官網地址:http://maven.apache.org/archetype/maven-archetype-plugin/
主要命令:
- archetype:generate 從項目骨架創建一個maven項目,老版本里使用的是archetype:create
- archetype:create-from-project 根據一個項目創建項目骨架
使用archetype:generate創建項目
mvn archetype:generate命令參數解釋
項目相關參數:
| 參數 |
含義 |
| groupId |
當前應用程序隸屬的Group的ID |
| artifactId |
當前應用程序的ID |
| package |
代碼生成時使用的根包的名字,如果沒有給出,默認使用archetypeGroupId |
原型有關參數表
| 參數 | 含義 |
| archetypeGroupId |
原型(archetype)的Group ID |
| archetypeArtifactId |
原型(archetype)ID |
| archetypeVersion |
原型(archetype)版本 |
| archetypeRepository |
包含原型(archetype)的資源庫 |
| archetypeCatalog |
archetype分類,這里按位置分類有: |
| filter |
查找時過濾artifactId or groupId:artifactId |
| package |
代碼生成時使用的根包的名字,如果沒有給出,默認使用archetypeGroupId |
命令示例:
新建一個簡單web項目
mvn archetype:generate -DgroupId=com.domain
-DartifactId=webappdemo
-Dpackage=com.domain.webappdemo
-DarchetypeArtifactId=maven-archetype-webapp
-Dversion=1.0 -DinteractiveMode=No
新建一個struts2 web項目
mvn archetype:generate -B -DgroupId=com.mycompany.mysystem
-DartifactId=myWebApp
-DarchetypeGroupId=org.apache.struts
-DarchetypeArtifactId=struts2-archetype-convention
-DarchetypeVersion=<CURRENT_STRUTS_VERSION>
-DremoteRepositories=http://struts.apache.org
maven默認提供的archetype類型可以參考http://maven.apache.org/guides/introduction/introduction-to-archetypes.html
從一個已有項目生成一個archetype
mvn clean archetype:create-from-project -Darchetype.properties=./archetype.properties -Darchetype.filteredExtentions=java,xml,jsp,properties,sql
這里首先定義了一個archetype.properties文件在命令行被執行的目錄,里面的內容是
tablePrefix是QucikStart項目里用到的,想在新項目中替換掉的內容。
-DfilteredExtentions,因為maven默認不會掃描sql文件,而這里是希望修改tablePrefix的.
properties參考http://maven.apache.org/archetype/maven-archetype-plugin/create-from-project-mojo.html
3.7、maven的項目對象模型
Maven包含了一個項目對象模型 (Project Object Model),一組標准集合,一個項目生命周期(Project Lifecycle),一個依賴管理系統(Dependency Management System),和用來運行定義在生命周期階段(phase)中插件(plugin)目標(goal)的邏輯。

項目對象模型 (Project Object Model)
一個maven工程都有一個pom.xml文件,通過pom.xml文件定義項目的坐標、項目依賴、項目信息、插件目標等。
依賴管理系統(Dependency Management System)
通過maven的依賴管理對項目所依賴的jar 包進行統一管理。 比如:項目依賴junit4.9,通過在pom.xml中定義junit4.9的依賴即使用junit4.9,如下所示是junit4.9的依賴定義:
<!-- 依賴關系 --> <dependencies> <!-- 此項目運行使用junit,所以此項目依賴junit --> <dependency> <!-- junit的項目名稱 --> <groupId>junit</groupId> <!-- junit的模塊名稱 --> <artifactId>junit</artifactId> <!-- junit版本 --> <version>4.9</version> <!-- 依賴范圍:單元測試時使用junit --> <scope>test</scope> </dependency> </dependencies>
一個項目生命周期(Project Lifecycle)
使用maven完成項目的構建,項目構建包括:清理、編譯、測試、部署等過程,maven將這些過程規范為一個生命周期,如下所示是生命周期的各各階段:

maven通過執行一些簡單命令即可實現上邊生命周期的各各過程,比如執行mvn compile執行編譯、執行mvn clean執行清理。
一組標准集合
maven將整個項目管理過程定義一組標准,比如:通過maven構建工程有標准的目錄結構,有標准的生命周期階段、依賴管理有標准的坐標定義等。
插件(plugin)目標(goal)
maven 管理項目生命周期過程都是基於插件完成的。
Maven坐標是一組可以惟一標識構件的三元組值
- groupId,代表構件的實體或組織例如:org.inspur.loushang
- artifactId,實際的構件的名稱,例如framework
- version,該構件件的版本號
-
packaging :定義Maven項目打包的方式,首先,打包方式通常與所生成構件的文件擴展名對應,如上例中的packaging為jar,最終的文件名為my-app-0.0.1-SNAPSHOT.jar。也可以打包成war, ear等。當不定義packaging的時候,Maven 會使用默認值jar
classifier: 該元素用來幫助定義構建輸出的一些附件。附屬構件與主構件對應,如上例中的主構件為my-app-0.0.1-SNAPSHOT.jar,該項目可能還會通過一些插件生成如my-app-0.0.1-SNAPSHOT-javadoc.jar,my-app-0.0.1-SNAPSHOT-sources.jar, 這樣附屬構件也就擁有了自己唯一的坐標
四、IDE中使用Maven(IDEA或Eclipse)
4.1、將現有項目轉換成Maven項目
如果有一個非maven的項目想轉換成maven管理的項目,只需如下操作即可:
在項目上右鍵,添加框架支持

選擇maven與其它想添加的框架

選擇允許自動導入

這樣就成功轉換成了一個maven項目
4.2、在IDEA中創建Maven項目

4.2.1、創建項目
4.1是一種創建maven項目的辦法,但不推薦,因為沒有使用統一的骨架,可以一開始就選擇創建maven項目,步驟如下:
步驟一:首先先創建一個project,上次我說過了創建一個project就是一個工作空間,在這里就是創建一個maven的工作空間

步驟二:選擇maven項目,指定骨架,這里選擇的是一個webapp,當然webapp骨架有非常多,這里選擇apache提供的

步驟三:填寫項目的座標,公司編號(一般倒置域名),項目名稱,版本:

步驟四:因為IDEA內置了Maven,可以選擇默認內置的Maven;當然最好是選擇自己安裝並配置好的環境,讓所有的IDE統一:

這里可以點綠色的小加號添加參數
步驟五:選擇項目名稱,位置,一般默認

點擊Finish項目就創建完成了,如下圖所示:

4.2.2、配置Tomcat
點擊右上角下拉框,選擇Edit Configurations,編輯配置

添加tomcat的配置

配置tocat服務器,命名,選擇tomcat版本,等想配置的信息;最關鍵的是需要將項目部署出去,可以直接擊fix

選擇war explored,他們的區別

當然也可以手動選擇要部署出去的項目,特別是有多個項目的情況

配置項目結構,特別是要注意依賴的包需要部署到WEB-INF的lib目錄下

完成后可以啟服務器,效果如下:

當然可以直接使用插件讓項目部署到jetty中通過maven運行,不需tomcat。
4.2.3、war和war exploded的區別

是選擇war還是war exploded 這里首先看一下他們兩個的區別:
(1)war模式這種可以稱之為是發布模式,看名字也知道,這是先打成war包,再發布;
(2)war exploded模式是直接把文件夾、jsp頁面 、classes等等移到Tomcat 部署文件夾里面,進行加載部署。因此這種方式支持熱部署,一般在開發的時候也是用這種方式。
(3)在平時開發的時候,使用熱部署的話,應該對Tomcat進行相應的設置,這樣的話修改的jsp界面什么的東西才可以及時的顯示出來。
兩種方式得部署方式是不一樣的,在獲取項目的路徑的時候得到的結果是不一樣的
String contextPath = request.getSession().getServletContext().getRealPath("/");
4.2.4、修改項目結構
maven有一個很重要的功能是規范項目,標准的項目結構如下所示:

但是你會發現默認創建的項並非是完整的,如寫源代碼的目錄沒有,添加方法如下
當前項目結構如下:

添加相應的目錄,選擇打開項目結構:

項目結構如下:

藍色:源代碼
綠色:測試
資源文件(配置信息)
測試資源文件
被排除的(打包里被忽視)
目標位置右鍵添加目錄:

添加后的目錄結構如下:

4.2.5、不能添加Servlet的解決方法
打開項目描述文件,指定源代碼目錄:
<sourceRoots> <root url="file://$MODULE_DIR$/src/main/java" /> </sourceRoots>
修改方法:

這樣就可以了:

如果沒有添加tomcat的配置信息或沒有servet的核心包也可能出現該問題,建議修改pom加上:
<!-- JSTL --> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency> <!-- Servlet核心包 --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.0.1</version> <scope>provided</scope> </dependency> <!--JSP --> <dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>jsp-api</artifactId> <version>2.1</version> <scope>provided</scope> </dependency>
4.3、在Eclipse中創建Maven工程
Maven插件
在Eclipse中創建Maven工程,需要安裝Maven插件。
一般較新版本的Eclipse都會帶有Maven插件,如果你的Eclipse中已經有Maven插件,可以跳過這一步驟。
點擊Help -> Eclipse Marketplace,搜索maven關鍵字,選擇安裝紅框對應的Maven插件。

Maven環境配置
點擊Window -> Preferences
如下圖所示,配置settings.xml文件的位置

創建Maven工程
File -> New -> Maven Project -> Next,在接下來的窗口中會看到一大堆的項目模板,選擇合適的模板。
接下來設置項目的參數,如下:
groupId是項目組織唯一的標識符,實際對應JAVA的包的結構,是main目錄里java的目錄結構。
artifactId就是項目的唯一的標識符,實際對應項目的名稱,就是項目根目錄的名稱。
點擊Finish,Eclipse會創建一個Maven工程。
4.4、使用Maven進行構建
Eclipse中構建方式
在Elipse項目上右擊 -> Run As 就能看到很多Maven操作。這些操作和maven命令是等效的。例如Maven clean,等同於mvn clean命令。
你也可以點擊Maven build,輸入組合命令,並保存下來。如下圖:

Maven命令構建方式
當然,你也可以直接使用maven命令進行構建。
進入工程所在目錄,輸入maven命令就可以了。
如下圖
4.5、創建Maven多模塊項目
多模塊項目不一定要使用Maven,普通項目也可以。
4.5.1、maven多模塊優點
1、復用,划分出來的模塊可以供其他項目使用。
2、固化,划分出來的某個模塊可讓專人開發,沉淀技術,分工協作。
3、優化依賴,每個模塊有各自的pom。
4、節省時間,可在單個模塊上進行build。
4.5.2、在IDEA中創建多模塊項目
1、創建父模塊
創建一個普通的Maven項目,不需要選擇骨架(archetype)

指定座標

完成后一個普通的Maven項目就創建好了

2、創建子模塊
子模塊可以有多個,相互間可以依賴
在父模塊上右鍵創建一個Module(模塊)

utils
創建普通maven項目沒有骨架

指定模塊名稱

完成后如下:

entities
創建成一個非maven項目(當然可以是maven的)

指定項目名稱

完成后

webapp
創建一個基於骨架的maven WebApp項目

設置名稱

選擇maven home

完成后的結果

3、模塊間依賴
方法一:依賴class
打開項目結構

添加模塊依賴

指定要依賴的模塊

依賴成功

指定輸出

最終項目結構

結果

方法一:通過座標直接依賴jar
hr-ui模塊的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"> <parent> <artifactId>HR</artifactId> <groupId>com.zhangguo.hr</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>hr-ui</artifactId> <packaging>war</packaging> <name>hr-ui Maven Webapp</name> <!-- FIXME change it to the project's website --> <url>http://www.example.com</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>1.7</maven.compiler.source> <maven.compiler.target>1.7</maven.compiler.target> </properties> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <scope>test</scope> </dependency> <dependency> <groupId>com.zhangguo.hr</groupId> <artifactId>hr-core</artifactId> <version>1.0-SNAPSHOT</version> </dependency> </dependencies> <build> <finalName>hr-ui</finalName> <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) --> <plugins> <plugin> <artifactId>maven-clean-plugin</artifactId> <version>3.0.0</version> </plugin> <!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging --> <plugin> <artifactId>maven-resources-plugin</artifactId> <version>3.0.2</version> </plugin> <plugin> <artifactId>maven-compiler-plugin</artifactId> <version>3.7.0</version> </plugin> <plugin> <artifactId>maven-surefire-plugin</artifactId> <version>2.20.1</version> </plugin> <plugin> <artifactId>maven-war-plugin</artifactId> <version>3.2.0</version> </plugin> <plugin> <artifactId>maven-install-plugin</artifactId> <version>2.5.2</version> </plugin> <plugin> <artifactId>maven-deploy-plugin</artifactId> <version>2.8.2</version> </plugin> </plugins> </pluginManagement> </build> </project>
結果

4.6、多模塊項目依賴管理與依賴繼承
4.6.1、指定父模塊與默認繼承
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>com.zhangguo.maven03</groupId> <artifactId>Maven03</artifactId> <packaging>pom</packaging> <version>1.0-SNAPSHOT</version> <modules> <module>Maven03-Dao</module> <module>Maven03-Service</module> </modules> <properties> <junit.version>4.12</junit.version> <spring.version>RELEASE</spring.version> </properties> <dependencies> <!-- junit --> <!-- https://mvnrepository.com/artifact/junit/junit --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>${junit.version}</version> <scope>test</scope> </dependency> </dependencies> </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 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <!--聲明自己的父模塊,將繼承父模塊的所有依賴--> <parent> <artifactId>Maven03</artifactId> <groupId>com.zhangguo.maven03</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>Maven03-Dao</artifactId> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> <version>${spring.version}</version> <!--版本是從父模塊依賴過來的properties--> </dependency> </dependencies> </project>
RELEASE表示最新的發布版本,結果如下:

4.6.2、依賴管理
dependencyManagement里只是聲明依賴,並不實現引入,因此子項目需要顯式的聲明需要用的依賴。如果不在子項目中聲明依賴,是不會從父項目中繼承下來的;只有在子項目中寫了該依賴項,並且沒有指定具體版本,才會從父項目中繼承該項,並且version和scope都讀取自父pom;另外如果子項目中指定了版本號,那么會使用子項目中指定的jar版本。
當我把父項目中的依賴放到依賴管理中的效果如下所示:
<?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>com.zhangguo.maven03</groupId> <artifactId>Maven03</artifactId> <packaging>pom</packaging> <version>1.0-SNAPSHOT</version> <modules> <module>Maven03-Dao</module> <module>Maven03-Service</module> </modules> <properties> <junit.version>4.12</junit.version> <spring.version>RELEASE</spring.version> </properties> <!--dependencyManagement里只是聲明依賴,並不實現引入, 因此子項目需要顯式的聲明需要用的依賴。 如果不在子項目中聲明依賴,是不會從父項目中繼承來的; 只有在子項目中寫了該依賴項,並且沒有指定具體版本,才會從父項目中繼承該項, 並且version和scope都讀取自父pom; 另外如果子項目中指定了版本號,那么會使用子項目中指定的jar版本。--> <dependencyManagement> <dependencies> <!-- junit --> <!-- https://mvnrepository.com/artifact/junit/junit --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>${junit.version}</version> <scope>test</scope> </dependency> </dependencies> </dependencyManagement> </project>
結果
這里的父模塊與子模塊都並沒有依賴junit了,這時的依賴只是用於管理,並沒有真正依賴。
<dependencyManagement>元素既能讓子模塊繼承到父模塊的依賴配置,又能保證子模塊依賴使用的靈活性。
使用<dependencyManagement>聲明的依賴即不會引入依賴,也不會給他的子模塊引入依賴。但這段配置是可以繼承的。
在子類中,依賴配置較原來就簡單了。可以在子類中只配置groupId和artifactId ,省去了version。因為完整的依賴聲明已經包含在父POM中。 這樣可以統一項目范圍中依賴的版本,幫助降低依賴沖突的幾率。
如果子模塊不聲明依賴的使用,即使該依賴已經在父POM的dependencyManangement中聲明了,也不會產生任何實際的效果。
如果想要在某個模塊中使用和另一個模塊中完全一樣的dependencyManagement配置,除了賦值和繼承外,還可以使用import范圍依賴將這一配置導入。
我們要達到的目的是:父模塊作版本管理不實際依賴,子模塊按需依賴。
父模塊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>com.zhangguo.maven03</groupId> <artifactId>Maven03</artifactId> <packaging>pom</packaging> <version>1.0-SNAPSHOT</version> <modules> <module>Maven03-Dao</module> <module>Maven03-Service</module> </modules> <!--版本管理--> <properties> <junit.version>4.12</junit.version> <spring.version>RELEASE</spring.version> </properties> <!--依賴聲明--> <dependencyManagement> <dependencies> <!-- junit --> <!-- https://mvnrepository.com/artifact/junit/junit --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>${junit.version}</version> <scope>test</scope> </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 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>Maven03</artifactId> <groupId>com.zhangguo.maven03</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>Maven03-Service</artifactId> <dependencies> <!--按需依賴,版本被父模塊控制,可以自行聲明,優先級更高--> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> </dependency> </dependencies> </project>
結果:

這樣做的好處:統一管理項目的版本號,確保應用的各個項目的依賴和版本一致,才能保證測試的和發布的是相同的成果,因此,在頂層pom中定義共同的依賴關系。同時可以避免在每個使用的子項目中都聲明一個版本號,這樣想升級或者切換到另一個版本時,只需要在父類容器里更新,不需要任何一個子項目的修改;如果某個子項目需要另外一個版本號時,只需要在dependencies中聲明一個版本號即可。子類就會使用子類聲明的版本號,不繼承於父類版本號。
五、Maven中常用指令使用
5.1、在命令行中使用Maven指令
1、 顯示版本信息
mvn -version
mvn -v
結果:

2、使用互動模式創建項目
mvn archetype:generate
結果:
具體請看本文前面:https://www.cnblogs.com/best/p/9622472.html#_lab2_1_4
3、使用非互動模式(指定參數創建項目)
普通項目骨架:
mvn archetype:generate -DgroupId=com.mycompany.app -DartifactId=myapp -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
Web項目骨架:
mvn archetype:generate -DgroupId=com.zhangguo -DartifactId=webappdemo -Dpackage=com.zhangguo.webappdemo -DarchetypeArtifactId=maven-archetype-webapp -Dversion=1.0 -DinteractiveMode=No
具體請看本文前面:https://www.cnblogs.com/best/p/9622472.html#_lab2_1_4
4、將項目轉化為idea項目
mvn idea:idea
結果:

5、將項目轉化為Eclipse項目
mvn eclipse:eclipse
結果:

6、編譯,將Java 源程序編譯成 class 字節碼文件
mvn compile
結果:

7、測試,並生成測試報告
mvn test
導入到idea中,添加測試用例

結果:

8、將以前編譯得到的舊的 class 字節碼文件刪除
mvn clean
結果:

9、打包,動態 web工程打 war包,Java工程打 jar 包
mvn pakage
結果:

10、將項目生成 jar 包放在倉庫中,以便別的模塊調用,安裝到本地
mvn install
結果:

在其它項目中依賴

11. 生成項目相關信息的網站:mvn site
12. 編譯測試的內容:mvn test-compile
13. 只打jar包:mvn jar:jar
14. 只打war包:mvn war:war
15. 清除eclipse的一些系統設置:mvn eclipse:clean
16. 運行項目於jetty上:mvn jetty:run
17. 生成Wtp插件的Web項目:mvn -Dwtpversion=1.0 eclipse:eclipse
18. 清除Eclipse項目的配置信息(Web項目):mvn -Dwtpversion=1.0 eclipse:clean
19、部署項目:
mvn deploy:deploy-file -DgroupId=com -DartifactId=client -Dversion=0.1.0 -Dpackaging=jar -Dfile=d:\client-0.1.0.jar -DrepositoryId=maven-repository-inner -Durl=ftp://xxxxxxx/opt/maven/repository/
其它指令:
mvn -e 顯示詳細錯誤 信息. mvn validate 驗證工程是否正確,所有需要的資源是否可用。 mvn test-compile 編譯項目測試代碼。 mvn integration-test 在集成測試可以運行的環境中處理和發布包。 mvn verify 運行任何檢查,驗證包是否有效且達到質量標准。 mvn generate-sources 產生應用需要的任何額外的源代碼,如xdoclet。 mvn help:describe -Dplugin=help 使用 help 插件的 describe 目標來輸出 Maven Help 插件的信息。 mvn help:describe -Dplugin=help -Dfull 使用Help 插件輸出完整的帶有參數的目標列 mvn help:describe -Dplugin=compiler -Dmojo=compile -Dfull 獲取單個目標的信息,設置 mojo 參數和 plugin 參數。此命令列出了Compiler 插件的compile 目標的所有信息 mvn help:describe -Dplugin=exec -Dfull 列出所有 Maven Exec 插件可用的目標 mvn help:effective-pom 看這個“有效的 (effective)”POM,它暴露了 Maven的默認設置 mvn archetype:create -DgroupId=org.sonatype.mavenbook.ch03 -DartifactId=simple -DpackageName=org.sonatype.mavenbook 創建Maven的普通java項目,在命令行使用Maven Archetype 插件 mvn exec:java -Dexec.mainClass=org.sonatype.mavenbook.weather.Main Exec 插件讓我們能夠在不往 classpath 載入適當的依賴的情況下,運行這個程序 mvn dependency:resolve 打印出已解決依賴的列表 mvn dependency:tree 打印整個依賴樹 mvn install -X 想要查看完整的依賴蹤跡,包含那些因為沖突或者其它原因而被拒絕引入的構件,打開 Maven 的調試標記運行 mvn install -Dmaven.test.skip=true 給任何目標添加maven.test.skip 屬性就能跳過測試 mvn install assembly:assembly 構建裝配Maven Assembly 插件是一個用來創建你應用程序特有分發包的插件 mvn jetty:run 調用 Jetty 插件的 Run 目標在 Jetty Servlet 容器中啟動 web 應用 mvn compile 編譯你的項目 mvn clean install 刪除再編譯 mvn hibernate3:hbm2ddl 使用 Hibernate3 插件構造數據庫
5.2、常用Maven命令
| 生命周期 |
階段描述 |
| mvn validate |
驗證項目是否正確,以及所有為了完整構建必要的信息是否可用 |
| mvn generate-sources |
生成所有需要包含在編譯過程中的源代碼 |
| mvn process-sources |
處理源代碼,比如過濾一些值 |
| mvn generate-resources |
生成所有需要包含在打包過程中的資源文件 |
| mvn process-resources |
復制並處理資源文件至目標目錄,准備打包 |
| mvn compile |
編譯項目的源代碼 |
| mvn process-classes |
后處理編譯生成的文件,例如對Java類進行字節碼增強(bytecode enhancement) |
| mvn generate-test-sources |
生成所有包含在測試編譯過程中的測試源碼 |
| mvn process-test-sources |
處理測試源碼,比如過濾一些值 |
| mvn generate-test-resources |
生成測試需要的資源文件 |
| mvn process-test-resources |
復制並處理測試資源文件至測試目標目錄 |
| mvn test-compile |
編譯測試源碼至測試目標目錄 |
| mvn test |
使用合適的單元測試框架運行測試。這些測試應該不需要代碼被打包或發布 |
| mvn prepare-package |
在真正的打包之前,執行一些准備打包必要的操作。這通常會產生一個包的展開的處理過的版本(將會在Maven 2.1+中實現) |
| mvn package |
將編譯好的代碼打包成可分發的格式,如JAR,WAR,或者EAR |
| mvn pre-integration-test |
執行一些在集成測試運行之前需要的動作。如建立集成測試需要的環境 |
| mvn integration-test |
如果有必要的話,處理包並發布至集成測試可以運行的環境 |
| mvn post-integration-test |
執行一些在集成測試運行之后需要的動作。如清理集成測試環境。 |
| mvn verify |
執行所有檢查,驗證包是有效的,符合質量規范 |
| mvn install |
安裝包至本地倉庫,以備本地的其它項目作為依賴使用 |
| mvn deploy |
復制最終的包至遠程倉庫,共享給其它開發人員和項目(通常和一次正式的發布相關) |
使用參數
-Dmaven.test.skip=true: 跳過單元測試(eg: mcn clean package -Dmaven.test.skip=true)

| mvn archetype:create | 創建Maven項目 |
| mvn compile | 編譯源代碼 |
| mvn test | 運行應用程序中的單元測試 |
| mvn install | 在本地Respository中安裝jar |
| mvn eclipse:eclipse | 生成eclipse項目文件 |
| mvn jetty:run | 啟動jetty服務 |
| mvn clean | 清除項目目錄中的生成結果 |
| mvn site | 生成項目相關信息的網站 |
| mvn package | 根據項目生成的jar |
5.3、在IDE(集成開發工具)中使用指令
5.3.1、工具欄介紹

圖標1:重新導入所有的maven項目,刷新
圖標2:重新生成所有源代碼並更新文件夾
圖標3:下載源碼或文件
圖標4:添加一個外部的Maven項目
圖標5:執行選擇的指令
圖標6:執行自定義的指令

圖標7:切換離線模式
圖標8:切換成跳過測試模式
圖標9:顯示依賴結構圖

圖標10:折疊所有
圖標11:Maven設置

5.3.2、快捷執行Maven命令
選擇命令后右鍵run

創建命令,可反復使用並指定名稱與參數

定義細節

執行

六、使用指導
6.1、如何添加外部依賴jar包
在POM文件中引入對應的<dependency>標簽即可
<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.zp.maven</groupId> <artifactId>MavenDemo</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>MavenDemo</name> <url>http://maven.apache.org</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <junit.version>3.8.1</junit.version> </properties> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>${junit.version}</version> <scope>test</scope> </dependency> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.12</version> <scope>compile</scope> </dependency> </dependencies> </project>
<dependency>標簽最常用的四個屬性標簽:
groupId:項目組織唯一的標識符,實際對應JAVA的包的結構。
artifactId:項目唯一的標識符,實際對應項目的名稱,就是項目根目錄的名稱。
version:jar包的版本號。可以直接填版本數字,也可以在properties標簽中設置屬性值。
scope:jar包的作用范圍。可以填寫compile、runtime、test、system和provided。用來在編譯、測試等場景下選擇對應的classpath
6.2、如何尋找jar包
可以在http://mvnrepository.com/站點搜尋你想要的jar包版本

6.3、如何使用Maven插件(Plugin)
要添加Maven插件,可以在pom.xml文件中添加<plugin>標簽。
<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>
6.4、如何一次編譯多個工程
在Maven中,允許一個Maven Project中有多個Maven Module
1.創建maven父工程步驟:new-->other-->選擇maven project-->next-->勾選create a simple project-->next-->填寫Group Id、Artifact Id、Version --> packaging選擇pom-->finish。

2.創建maven子工程步驟:選中剛才創建的父工程右鍵-->new-->other-->選擇maven module-->next-->勾選create a simple project-->填寫module name(其實就是artifact id)-->next-->GAV繼承父工程-->packaging選擇你需要的-->finish。

3.完成,刷新父工程;如有多個子工程,繼續按照第二步驟創建。

這時打開XXX中的pom.xml可以看到其中有以下標簽
<modules> <module>xxx1</module> </modules>
選擇編譯XXX時,會依次對它的所有Module執行相同操作。
6.5、常用Maven插件
Maven 是一個執行插件的框架,每一個任務實際上是由插件完成的。Maven 提供以下兩種類型插件:構建插件,在生成過程中執行,並在 pom.xml 中的<build/> 元素進行配置;報告插件,在網站生成期間執行,在 pom.xml 中的 <reporting/> 元素進行配置。
maven-antrun-plugin
http://maven.apache.org/plugins/maven-antrun-plugin/
maven-antrun-plugin能讓用戶在Maven項目中運行Ant任務。用戶可以直接在該插件的配置以Ant的方式編寫Target,然后交給該插件的run目標去執行。在一些由Ant往Maven遷移的項目中,該插件尤其有用。此外當你發現需要編寫一些自定義程度很高的任務,同時又覺得Maven不夠靈活時,也可以以Ant的方式實現之。maven-antrun-plugin的run目標通常與生命周期綁定運行。
maven-archetype-plugin
http://maven.apache.org/archetype/maven-archetype-plugin/
Archtype指項目的骨架,Maven初學者最開始執行的Maven命令可能就是mvn archetype:generate,這實際上就是讓maven-archetype-plugin生成一個很簡單的項目骨架,幫助開發者快速上手。可能也有人看到一些文檔寫了mvn archetype:create,但實際上create目標已經被棄用了,取而代之的是generate目標,該目標使用交互式的方式提示用戶輸入必要的信息以創建項目,體驗更好。 maven-archetype-plugin還有一些其他目標幫助用戶自己定義項目原型,例如你由一個產品需要交付給很多客戶進行二次開發,你就可以為他們提供一個Archtype,幫助他們快速上手。
maven-assembly-plugin
http://maven.apache.org/plugins/maven-assembly-plugin/
maven-assembly-plugin的用途是制作項目分發包,該分發包可能包含了項目的可執行文件、源代碼、readme、平台腳本等等。 maven-assembly-plugin支持各種主流的格式如zip、tar.gz、jar和war等,具體打包哪些文件是高度可控的,例如用戶可以按文件級別的粒度、文件集級別的粒度、模塊級別的粒度、以及依賴級別的粒度控制打包,此外,包含和排除配置也是支持的。maven-assembly- plugin要求用戶使用一個名為assembly.xml的元數據文件來表述打包,它的single目標可以直接在命令行調用,也可以被綁定至生命周期。
maven-dependency-plugin
http://maven.apache.org/plugins/maven-dependency-plugin/
maven-dependency-plugin最大的用途是幫助分析項目依賴,dependency:list能夠列出項目最終解析到的依賴列表,dependency:tree能進一步的描繪項目依賴樹,dependency:analyze可以告訴你項目依賴潛在的問題,如果你有直接使用到的卻未聲明的依賴,該目標就會發出警告。maven-dependency-plugin還有很多目標幫助你操作依賴文件,例如dependency:copy-dependencies能將項目依賴從本地Maven倉庫復制到某個特定的文件夾下面。
maven-enforcer-plugin
http://maven.apache.org/plugins/maven-enforcer-plugin/
在一個稍大一點的組織或團隊中,你無法保證所有成員都熟悉Maven,那他們做一些比較愚蠢的事情就會變得很正常,例如給項目引入了外部的 SNAPSHOT依賴而導致構建不穩定,使用了一個與大家不一致的Maven版本而經常抱怨構建出現詭異問題。maven-enforcer- plugin能夠幫助你避免之類問題,它允許你創建一系列規則強制大家遵守,包括設定Java版本、設定Maven版本、禁止某些依賴、禁止 SNAPSHOT依賴。只要在一個父POM配置規則,然后讓大家繼承,當規則遭到破壞的時候,Maven就會報錯。除了標准的規則之外,你還可以擴展該插件,編寫自己的規則。maven-enforcer-plugin的enforce目標負責檢查規則,它默認綁定到生命周期的validate階段。
maven-help-plugin
http://maven.apache.org/plugins/maven-help-plugin/
maven-help-plugin是一個小巧的輔助工具,最簡單的help:system可以打印所有可用的環境變量和Java系統屬性。help:effective-pom和help:effective-settings最為有用,它們分別打印項目的有效POM和有效settings,有效POM是指合並了所有父POM(包括Super POM)后的XML,當你不確定POM的某些信息從何而來時,就可以查看有效POM。有效settings同理,特別是當你發現自己配置的 settings.xml沒有生效時,就可以用help:effective-settings來驗證。此外,maven-help-plugin的describe目標可以幫助你描述任何一個Maven插件的信息,還有all-profiles目標和active-profiles目標幫助查看項目的Profile。
maven-release-plugin
http://maven.apache.org/plugins/maven-release-plugin/
maven-release-plugin的用途是幫助自動化項目版本發布,它依賴於POM中的SCM信息。release:prepare用來准備版本發布,具體的工作包括檢查是否有未提交代碼、檢查是否有SNAPSHOT依賴、升級項目的SNAPSHOT版本至RELEASE版本、為項目打標簽等等。release:perform則是簽出標簽中的RELEASE源碼,構建並發布。版本發布是非常瑣碎的工作,它涉及了各種檢查,而且由於該工作僅僅是偶爾需要,因此手動操作很容易遺漏一些細節,maven-release-plugin讓該工作變得非常快速簡便,不易出錯。maven-release-plugin的各種目標通常直接在命令行調用,因為版本發布顯然不是日常構建生命周期的一部分。
maven-resources-plugin
http://maven.apache.org/plugins/maven-resources-plugin/
為了使項目結構更為清晰,Maven區別對待Java代碼文件和資源文件,maven-compiler-plugin用來編譯Java代碼,maven-resources-plugin則用來處理資源文件。默認的主資源文件目錄是src/main/resources,很多用戶會需要添加額外的資源文件目錄,這個時候就可以通過配置maven-resources-plugin來實現。此外,資源文件過濾也是Maven的一大特性,你可以在資源文件中使用${propertyName}形式的Maven屬性,然后配置maven-resources-plugin開啟對資源文件的過濾,之后就可以針對不同環境通過命令行或者Profile傳入屬性的值,以實現更為靈活的構建。
maven-surefire-plugin
http://maven.apache.org/plugins/maven-surefire-plugin/
可能是由於歷史的原因,Maven 2/3中用於執行測試的插件不是maven-test-plugin,而是maven-surefire-plugin。其實大部分時間內,只要你的測試類遵循通用的命令約定(以Test結尾、以TestCase結尾、或者以Test開頭),就幾乎不用知曉該插件的存在。然而在當你想要跳過測試、排除某些測試類、或者使用一些TestNG特性的時候,了解maven-surefire-plugin的一些配置選項就很有用了。例如 mvn test -Dtest=FooTest 這樣一條命令的效果是僅運行FooTest測試類,這是通過控制maven-surefire-plugin的test參數實現的。
build-helper-maven-plugin
http://mojo.codehaus.org/build-helper-maven-plugin/
Maven默認只允許指定一個主Java代碼目錄和一個測試Java代碼目錄,雖然這其實是個應當盡量遵守的約定,但偶爾你還是會希望能夠指定多個源碼目錄(例如為了應對遺留項目),build-helper-maven-plugin的add-source目標就是服務於這個目的,通常它被綁定到默認生命周期的generate-sources階段以添加額外的源碼目錄。需要強調的是,這種做法還是不推薦的,因為它破壞了 Maven的約定,而且可能會遇到其他嚴格遵守約定的插件工具無法正確識別額外的源碼目錄。
build-helper-maven-plugin的另一個非常有用的目標是attach-artifact,使用該目標你可以以classifier的形式選取部分項目文件生成附屬構件,並同時install到本地倉庫,也可以deploy到遠程倉庫。
exec-maven-plugin
http://mojo.codehaus.org/exec-maven-plugin/
exec-maven-plugin很好理解,顧名思義,它能讓你運行任何本地的系統程序,在某些特定情況下,運行一個Maven外部的程序可能就是最簡單的問題解決方案,這就是exec:exec的用途,當然,該插件還允許你配置相關的程序運行參數。除了exec目標之外,exec-maven-plugin還提供了一個java目標,該目標要求你提供一個mainClass參數,然后它能夠利用當前項目的依賴作為classpath,在同一個JVM中運行該mainClass。有時候,為了簡單的演示一個命令行Java程序,你可以在POM中配置好exec-maven-plugin的相關運行參數,然后直接在命令運行mvn exec:java 以查看運行效果。
jetty-maven-plugin
http://wiki.eclipse.org/Jetty/Feature/Jetty_Maven_Plugin
在進行Web開發的時候,打開瀏覽器對應用進行手動的測試幾乎是無法避免的,這種測試方法通常就是將項目打包成war文件,然后部署到Web容器中,再啟動容器進行驗證,這顯然十分耗時。為了幫助開發者節省時間,jetty-maven-plugin應運而生,它完全兼容 Maven項目的目錄結構,能夠周期性地檢查源文件,一旦發現變更后自動更新到內置的Jetty Web容器中。做一些基本配置后(例如Web應用的contextPath和自動掃描變更的時間間隔),你只要執行 mvn jetty:run ,然后在IDE中修改代碼,代碼經IDE自動編譯后產生變更,再由jetty-maven-plugin偵測到后更新至Jetty容器,這時你就可以直接測試Web頁面了。需要注意的是,jetty-maven-plugin並不是宿主於Apache或Codehaus的官方插件,因此使用的時候需要額外的配置settings.xml的pluginGroups元素,將org.mortbay.jetty這個pluginGroup加入。
versions-maven-plugin
http://mojo.codehaus.org/versions-maven-plugin/
很多Maven用戶遇到過這樣一個問題,當項目包含大量模塊的時候,為他們集體更新版本就變成一件煩人的事情,到底有沒有自動化工具能幫助完成這件事情呢?(當然你可以使用sed之類的文本操作工具,不過不在本文討論范圍)答案是肯定的,versions-maven- plugin提供了很多目標幫助你管理Maven項目的各種版本信息。例如最常用的,命令 mvn versions:set -DnewVersion=1.1-SNAPSHOT 就能幫助你把所有模塊的版本更新到1.1-SNAPSHOT。該插件還提供了其他一些很有用的目標,display-dependency- updates能告訴你項目依賴有哪些可用的更新;類似的display-plugin-updates能告訴你可用的插件更新;然后use- latest-versions能自動幫你將所有依賴升級到最新版本。最后,如果你對所做的更改滿意,則可以使用 mvn versions:commit 提交,不滿意的話也可以使用 mvn versions:revert 進行撤銷。
更多詳情請參考https://maven.apache.org/plugins/
七、常見問題
7.1、dependencies和dependencyManagement,plugins和pluginManagement的區別?
dependencyManagement是表示依賴jar包的聲明,即你在項目中的dependencyManagement下聲明了依賴,maven不會加載該依賴,dependencyManagement聲明可以被繼承。
dependencyManagement的一個使用案例是當有父子項目的時候,父項目中可以利用dependencyManagement聲明子項目中需要用到的依賴jar包,之后,當某個或者某幾個子項目需要加載該插件的時候,就可以在子項目中dependencies節點只配置 groupId 和 artifactId就可以完成插件的引用。
dependencyManagement主要是為了統一管理插件,確保所有子項目使用的插件版本保持一致,類似的還是plugins和pluginManagement。
7.2、不能添加Servlet
1、修改項目文件.iml,添加如下內容
<sourceRoots> <root url="file://$MODULE_DIR$/src/main/java" /> </sourceRoots>
2、添加Servlet-api核心包
八、綜合示例
這里使用Maven+多模塊項目+IDEA+Git+MySQL完成一個簡單的綜合示例,完成一個TaskList項目,實現任務管理功能。
8.1、創建項目

8.2、創建數據數據庫與表

創建表

添加數據

8.3、編寫實體模塊

8.4、編寫工具模塊

8.5、數據訪問模塊
添加依賴

修改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"> <parent> <artifactId>TaskList</artifactId> <groupId>com.zhangguo.tasklist</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>taskList-dao</artifactId> <dependencies> <dependency> <groupId>com.zhangguo.tasklist</groupId> <artifactId>taskList-entities</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <dependency> <groupId>com.zhangguo.tasklist</groupId> <artifactId>taskList-utils</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <!-- JUnit單元測試工具 --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.10</version> </dependency> </dependencies> </project>
編寫任務表的數據訪問類
package com.zhangguo.tasklist.dao; import com.zhangguo.tasklist.entities.Task; import com.zhangguo.tasklist.utils.JDBCUtils; import java.util.List; public class TaskDao { /**獲得所有任務清單*/ public List<Task> getAllTasks(){ return JDBCUtils.queryForList("select id,title,status from task",Task.class); } }
8.6、單元測試

8.7、服務模塊
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"> <parent> <artifactId>TaskList</artifactId> <groupId>com.zhangguo.tasklist</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>taskList-services</artifactId> <dependencies> <dependency> <groupId>com.zhangguo.tasklist</groupId> <artifactId>taskList-dao</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <dependency> <groupId>com.zhangguo.tasklist</groupId> <artifactId>taskList-entities</artifactId> <version>1.0-SNAPSHOT</version> </dependency> </dependencies> </project>
代碼:

8.8、Web項目
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"> <parent> <artifactId>TaskList</artifactId> <groupId>com.zhangguo.tasklist</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>taskList-ui</artifactId> <packaging>war</packaging> <name>taskList-ui Maven Webapp</name> <!-- FIXME change it to the project's website --> <url>http://www.example.com</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>1.7</maven.compiler.source> <maven.compiler.target>1.7</maven.compiler.target> </properties> <dependencies> <dependency> <groupId>com.zhangguo.tasklist</groupId> <artifactId>taskList-utils</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <dependency> <groupId>com.zhangguo.tasklist</groupId> <artifactId>taskList-services</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <!-- JSTL --> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency> <!-- Servlet核心包 --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.0.1</version> <scope>provided</scope> </dependency> <!--JSP --> <dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>jsp-api</artifactId> <version>2.1</version> <scope>provided</scope> </dependency> </dependencies> <build> <finalName>taskList-ui</finalName> <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) --> <plugins> <plugin> <artifactId>maven-clean-plugin</artifactId> <version>3.0.0</version> </plugin> <!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging --> <plugin> <artifactId>maven-resources-plugin</artifactId> <version>3.0.2</version> </plugin> <plugin> <artifactId>maven-compiler-plugin</artifactId> <version>3.7.0</version> </plugin> <plugin> <artifactId>maven-surefire-plugin</artifactId> <version>2.20.1</version> </plugin> <plugin> <artifactId>maven-war-plugin</artifactId> <version>3.2.0</version> </plugin> <plugin> <artifactId>maven-install-plugin</artifactId> <version>2.5.2</version> </plugin> <plugin> <artifactId>maven-deploy-plugin</artifactId> <version>2.8.2</version> </plugin> </plugins> </pluginManagement> </build> </project>
Servlet:
package com.zhangguo.tasklist.ui.controllers; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import com.zhangguo.tasklist.services.ITaskService; import com.zhangguo.tasklist.services.TaskService; import com.zhangguo.tasklist.utils.R; @WebServlet("/TaskServlet") public class TaskServlet extends HttpServlet { ITaskService service=new TaskService(); protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request,response); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //設置編碼 response.setCharacterEncoding("utf-8"); response.setContentType("application/json;charset=utf-8"); request.setCharacterEncoding("utf-8"); String json=R.ok(service.queryAllTask()).Json(); response.getWriter().write(json); } }
項目結構:

目錄結構:

運行結果:

8.9、Git同步到遠程倉庫
Git位置:https://git.coding.net/zhangguo5/TaskListSys.git

九、視頻
https://www.bilibili.com/video/av31623453/
十、作業
1、請下載、安裝配置好maven,在控制台輸出版本號
2、請配置本地倉庫路徑與遠程倉庫的鏡像
3、請在命令行模式下新建一個maven普通項目,導入到IDEA中,運行,打包輸出結果
4、請在命令行模式下新建一個webapp項目,使用jetty運行,要求輸出服務器時間,注意添加相應的javaEE依賴
參數pom
<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.zhangguo</groupId> <artifactId>ssm</artifactId> <version>0.0.1</version> <packaging>war</packaging> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <spring.version>4.3.0.RELEASE</spring.version> </properties> <dependencies> <!--Spring框架核心庫 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.version}</version> </dependency> <!-- Spring MVC --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> <version>${spring.version}</version> </dependency> <!-- aspectJ AOP 織入器 --> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.8.9</version> </dependency> <!--mybatis-spring適配器 --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>1.3.0</version> </dependency> <!--Spring java數據庫訪問包,在本例中主要用於提供數據源 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>${spring.version}</version> </dependency> <!--mysql數據庫驅動 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.38</version> </dependency> <!--log4j日志包 --> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <version>2.6.1</version> </dependency> <!-- mybatis ORM框架 --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.4.1</version> </dependency> <!-- JUnit單元測試工具 --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.10</version> </dependency> <!--c3p0 連接池 --> <dependency> <groupId>c3p0</groupId> <artifactId>c3p0</artifactId> <version>0.9.1.2</version> </dependency> <!-- JSTL --> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency> <!-- Servlet核心包 --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.0.1</version> <scope>provided</scope> </dependency> <!--JSP --> <dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>jsp-api</artifactId> <version>2.1</version> <scope>provided</scope> </dependency> <!-- jackson --> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>2.5.2</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.5.2</version> </dependency> <!--JSR303 --> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-validator</artifactId> <version>5.2.2.Final</version> </dependency> <!--文件上傳 --> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.4</version> </dependency> <dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.3.1</version> </dependency> <!-- FreeMarker --> <dependency> <groupId>org.freemarker</groupId> <artifactId>freemarker</artifactId> <version>2.3.23</version> </dependency> </dependencies> </project>
5、個人項目功能需求列表,下周五前提交
6、將考試的兩個項目修改成Maven項目,管理所有的包,測試運行通過
7、預習Git,安裝好環境,到coding.net上注冊一個帳號
8、完成任務指導手冊中所有的理論題
9、將考試中的兩個項目合並成一個多模塊的Maven項目,兩個ui層,一個使用jstl一個使用純HTML
10、熟練使用maven中常用的指令,自定義一個Maven項目,編寫測試用例,部署到本地倉庫並在其它項目中引用
2018-09-21
11、根據任務列表示例完成一個汽車管理系統CarSystem(車名,顏色,速度,車牌,詳細描述),實現增加、修改、刪除、查詢功能;最終完成的項目要求同步到遠程倉庫;
12、完成Git中協同開發的8個場景,2人以上交叉扮演組長與組員
13、完成任務指導手冊中的理論題
14、完成個人項目的功能需求,提交給學習委員
15、完成個人項目的數據庫設計,提交給組長,組長給學習委員
16、補考的同學請下周二上課前完成試題,並通過學習委員的檢查



