都是一樣的代碼,爲何在個人機器上能夠編譯執行,而在他的機器上就不行? java
爲何在個人機器上能夠正常打包,而配置管理員卻打不出來? mysql
項目組加入了新的人員,我要給他說明編譯環境如何設置,可是讓我撓頭的是,有些細節我也記不清楚了git
個人項目依賴一些jar包,我應該把他們放哪裏?放源碼庫裏?github
這是我開發的第二個項目,仍是須要上面的那些jar包,再把它們複製到我當前項目的svn庫裏吧 web
如今是第三次,再複製一次吧 —– 這樣真的好嗎? spring
我寫了一個數據庫相關的通用類,而且推薦給了其餘項目組,如今已經有五個項目組在使用它了,今天我發現了一個bug,並修正了它,我會把jar包經過郵件發給其餘項目組,這不是一個好的分發機制,太多的環節可能致使出現bugsql
項目進入測試階段,天天都要向測試服務器部署一版。每次都手動部署,太麻煩了 數據庫
官方網站:http://maven.apache.orgapache
本課程使用的maven的版本爲3.0.5json
用戶配置
4.1 聽從Maven約定
src/main/java —— 存放項目的.java文件
src/main/resources —— 存放項目資源文件,如spring, hibernate配置文件
src/test/java —— 存放全部測試.java文件,如JUnit測試類
src/test/resources —— 測試資源文件
target —— 項目輸出位置
pom.xml——maven項目核心配置文件
Project
|-src
| |-main
| | |-java —— 存放項目的.java文件
| | |-resources —— 存放項目資源文件,如spring, hibernate配置文件
| |-test
| |-java ——存放全部測試.java文件,如JUnit測試類
| |-resources —— 測試資源文件
|-target —— 目標文件輸出位置例如.class、.jar、.war文件
|-pom.xml ——maven項目核心配置文件
4.2 第一步:建立maven工程
首先創建MavenHelloWorld項目同時創建Maven約定的目錄結構
MavenHelloWorld
|-src
| |-main
| | |-java —— 存放項目的.java文件
| | |-resources —— (暫時省略)
| |-test
| |-java ——存放全部測試.java文件,如JUnit測試類
| |-resources —— (暫時省略)
|-target —— (不手工建立)
|-pom.xml ——maven項目核心配置文件
4.3 第二步:建立HelloWorld.java
在src/main/java/cn/change/maven目錄下新建文件Hello.java
package cn.change.maven;
public class HelloWorld {
public String sayHello(String name){
return "Hello World :" + name + "!";
}
}
4.4 第三步:新建測試文件HelloTest.java
在/src/test/java/cn/change/maven目錄下新建測試文件HelloTest.java
package cn.change.maven;
import org.junit.Test;
import static junit.framework.Assert.*;
public class HelloWorldTest{
@Test
public void testHello(){
HelloWorld hello = new HelloWorld();
String results = hello.sayHello("maven");
assertEquals("Hello World :maven!",results);
}
}
4.5 第四步:建立pom.xml
在項目MavenHelloWorld根目錄創建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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.bshinfo.el</groupId>
<artifactId>ccb_el_manager</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>ccb_el_manager Maven Webapp</name>
<url>http://maven.apache.org</url>
<packaging>war</packaging>
<build>
<finalName>ccb_el_manager</finalName>
</build>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<!-- spring jar -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.2.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.2.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>4.2.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>4.2.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>4.2.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>4.2.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>4.2.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
<version>4.0.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>4.0.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>4.0.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-cas</artifactId>
<version>4.0.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jms</artifactId>
<version>4.2.5.RELEASE</version>
</dependency>
<!-- spring mvc jar -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.2.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.2.5.RELEASE</version>
</dependency>
<!-- mybatis jar -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.3.1</version>
</dependency>
<!-- mybatis-paginator jar -->
<dependency>
<groupId>com.github.miemiedev</groupId>
<artifactId>mybatis-paginator</artifactId>
<version>1.2.10</version>
</dependency>
<!-- mybatis-spring jar -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.2.4</version>
</dependency>
<!-- mysql-connector-java jar -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.38</version>
</dependency>
<!-- 數據庫鏈接池 jar -->
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>commons-pool</groupId>
<artifactId>commons-pool</artifactId>
<version>1.6</version>
</dependency>
<!-- log jar -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.19</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.19</version>
</dependency>
<!-- jsp Template jar -->
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.23</version>
</dependency>
<!-- apache servlet api jar -->
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-servlet-api</artifactId>
<version>8.0.32</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.9</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.8.9</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjtools</artifactId>
<version>1.8.9</version>
</dependency>
<!-- activemq -->
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-core</artifactId>
<version>5.7.0</version>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-pool</artifactId>
<version>5.13.2</version>
</dependency>
<!-- cas security -->
<dependency>
<groupId>org.jasig.cas.client</groupId>
<artifactId>cas-client-core</artifactId>
<version>3.4.1</version>
</dependency>
<!-- end of cas security -->
<dependency>
<groupId>net.sf.json-lib</groupId>
<artifactId>json-lib</artifactId>
<version>2.4</version>
<classifier>jdk15</classifier>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.10</version>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.5.0</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.2.2</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-io</artifactId>
<version>1.3.2</version>
</dependency>
</dependencies>
</project>
4.6 第五步:測試maven命令
4.6.1 mvn compile命令
4.6.2 mvn clean命令
4.6.3 mvn test命令
4.6.4 mvn clean compile命令
4.6.5 mvn clean test命令
4.6.6 mvn clean package命令
5.3 建立maven工程
5.3.3 第二個maven工程
第三步:點擊finish完成。
5.3.3.2 修改pom文件
package cn.change.second;
import cn.change.first.First;
public class Second {
public String say(String name) {
First first = new First();
String result = first.say(name);
return result + ":second";
}
}
- 5.3.3.4 建立SecondTest.java
package cn.change.sencond;
import org.junit.Assert;
import org.junit.Test;
import cn.change.second.Second;
public class SecondTest {
@Test
public void testSay() {
Second second = new Second();
String result = second.say("張三");
Assert.assertEquals("hello 張三:first:second", result);
}
}
- 5.3.3.5 測試工程 - ![這裏寫圖片描述](http://img.blog.csdn.net/20160905135716735) - 若是maven-first工程沒有安裝則會出現如下錯誤:
[INFO] Scanning for projects…
[INFO]
[INFO] ————————————————————————
[INFO] Building maven-second 0.0.1-SNAPSHOT
[INFO] ————————————————————————
[WARNING] The POM for cn.change:maven-first:jar:0.0.1-SNAPSHOT is missing, no dependency information available
[INFO] ————————————————————————
[INFO] BUILD FAILURE
[INFO] ————————————————————————
[INFO] Total time: 0.218s
[INFO] Finished at: Fri Sep 25 15:06:00 CST 2015
[INFO] Final Memory: 4M/15M
[INFO] ————————————————————————
[ERROR] Failed to execute goal on project maven-second: Could not resolve dependencies for project cn.change:maven-second:jar:0.0.1-SNAPSHOT: Could not find artifact cn.change:maven-first:jar:0.0.1-SNAPSHOT -> [Help 1]
[ERROR]
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/DependencyResolutionException
提示找不到maven-first的jar包。當系統運行時是從本地倉庫中找依賴的jar包的,因此必須先將maven-first安裝才能正常運行,須要在maven-first工程上運行 mvn install命令安裝到本地倉庫。
- 5.3.4 第三個工程 - 建立第三個工程此工程使用maven-second工程中的Second的方法,並測試。 - 5.3.4.1 建立工程 - ![這裏寫圖片描述](http://img.blog.csdn.net/20160905135828749) - 5.3.4.2 修改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>cn.change</groupId>
<artifactId>maven-third</artifactId>
<version>0.0.1-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.9</version>
<scope>test</scope>
</dependency>
<!-- 依賴maven-first工程 -->
<dependency>
<groupId>cn.change</groupId>
<artifactId>maven-second</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
- 5.3.4.3 依賴關係 - ![這裏寫圖片描述](http://img.blog.csdn.net/20160905135916970) - 5.3.4.4 建立Third.java
package cn.change.third;
import cn.change.second.Second;
public class Third {
public String say(String name) {
Second second = new Second();
String result = second.say(name);
return result + ":third";
}
}
- 5.3.4.5 建立ThirdTest.java
package cn.change.third;
import org.junit.Assert;
import org.junit.Test;
public class ThirdTest {
@Test
public void testSay() {
Third third = new Third();
String result = third.say("張三");
Assert.assertEquals("hello 張三:first:second:third", result);
}
}
Maven的核心概念包括:座標、依賴管理、倉庫管理、生命週期、插件和目標、
聚合繼承。
6.1 座標
6.1.1 什麼是座標
6.1.2 Maven座標主要組成
6.1.3 Maven爲何使用座標
<dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.10</version> <scope>test</scope> </dependency>
`
6.2 依賴管理
其中依賴範圍scope 用來控制依賴和編譯,測試,運行的classpath的關係. 主要的是三種依賴關係以下:
1.compile: 默認編譯依賴範圍。對於編譯,測試,運行三種classpath都有效
若是Two中使用One,Three中使用Two則稱Two是Three的直接依賴,而稱One是Three的間接依賴。
C->B B->A
C直接依賴B
C間接依賴A
Maven生命週期就是爲了對全部的構建過程進行抽象和統一。包括項目清理,初始化,編譯,打包,測試,部署等幾乎全部構建步驟。
生命週期能夠理解爲構建工程的步驟。在Maven中有三套相互獨立的生命週期,請注意這裏說的是「三套」,並且「相互獨立」,這三套生命週期分別是:
Clean Lifecycle 在進行真正的構建以前進行一些清理工做。 Default Lifecycle
構建的核心部分,編譯,測試,打包,部署等等。 Site Lifecycle 生成項目報告,站點,發佈站點。
再次強調一下它們是相互獨立的,你能夠僅僅調用clean來清理工做目錄,僅僅調用site來生成站點。固然你也能夠直接運行 mvn clean
install site 運行全部這三套生命週期。
clean生命週期每套生命週期都由一組階段(Phase)組成,咱們平時在命令行輸入的命令總會對應於一個特定的階段。好比,運行mvn clean ,這個的clean是Clean生命週期的一個階段。有Clean生命週期,也有clean階段。Clean生命週期一共包含了三個階段:
pre-clean 執行一些須要在clean以前完成的工做 clean 移除全部上一次構建生成的文件 post-clean
執行一些須要在clean以後馬上完成的工做mvn clean 中的clean就是上面的clean,在一個生命週期中,運行某個階段的時候,它以前的全部階段都會被運行,也就是說,mvn
clean 等同於 mvn pre-clean clean ,若是咱們運行 mvn post-clean ,那麼
pre-clean,clean 都會被運行。這是Maven很重要的一個規則,能夠大大簡化命令行的輸入。
- 6.3.2.2 default:構建項目 -
Default生命週期Default生命週期是Maven生命週期中最重要的一個,絕大部分工做都發生在這個生命週期中。這裏,只解釋一些比較重要和經常使用的階段:
validate generate-sources process-sources generate-resources
process-resources 複製並處理資源文件,至目標目錄,準備打包。 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
將最終的包複製到遠程的倉庫,以讓其它開發人員與項目共享。運行任何一個階段的時候,它前面的全部階段都會被運行,這也就是爲何咱們運行mvn install
的時候,代碼會被編譯,測試,打包。此外,Maven的插件機制是徹底依賴Maven的生命週期的,所以理解生命週期相當重要。
- 6.3.2.3 site:生成項目站點 -
Site生命週期
pre-site 執行一些須要在生成站點文檔以前完成的工做
site 生成項目的站點文檔
post-site 執行一些須要在生成站點文檔以後完成的工做,而且爲部署作準備
site-deploy 將生成的站點文檔部署到特定的服務器上
這裏常常用到的是site階段和site-deploy階段,用以生成和發佈Maven站點,這但是Maven至關強大的功能,Manager比較喜歡,文檔及統計數據自動生成,很好看。
6.4 Maven插件