Maven
? Maven【[?mev?n]】這個(gè)詞可以翻譯為"專家",“內(nèi)行”秉版。 作為Apache組織中的一個(gè)頗為成功的開源項(xiàng)目达吞,Maven主要服務(wù)于基于java平臺(tái)的項(xiàng)目構(gòu)建,依賴管理和項(xiàng)目信息管理。
? 無論是小型的開源類庫(kù)項(xiàng)目痴荐,還是大型的企業(yè)級(jí)應(yīng)用列肢; 無論是傳統(tǒng)的瀑布式開發(fā)恰画,還是流行的敏捷開發(fā),Maven都能大顯身手瓷马。
? 不管你是否意識(shí)到拴还,構(gòu)建(build)是每一位程序員每天都在做的工作。早上來到公司欧聘,我們做的第一件事就是從源碼庫(kù)簽出最新的代碼片林,然后進(jìn)行單元測(cè)試,如果測(cè)試失敗,會(huì)找相關(guān)的同事一起調(diào)試费封,修復(fù)錯(cuò)誤代碼焕妙。 接著回到自己的工作上來,編寫自己的單元測(cè)試及產(chǎn)品代碼孝偎。
? 仔細(xì)總結(jié)一下访敌,我們會(huì)發(fā)現(xiàn),除了編寫源代碼衣盾,我們每天有相當(dāng)一部分時(shí)間花在了編譯寺旺,運(yùn)行單元測(cè)試,生成文檔势决,打包和部署等繁瑣且不起眼的工作上阻塑,這就是構(gòu)建。 如果我們現(xiàn)在還手工這樣做果复,那成本也太高了陈莽,于是有人用軟件的方法讓這一系列工作完全自動(dòng)化,使得軟件的構(gòu)建可以像全自動(dòng)流水線一樣虽抄,只需要一條簡(jiǎn)單的命令走搁,所有繁瑣的步驟都能夠自動(dòng)完成,很快就能得到最終結(jié)果迈窟。
??Ant構(gòu)建
? 最早的構(gòu)建工具私植,基于IDE, 大概是2000年有的,當(dāng)時(shí)是最流行java構(gòu)建工具车酣,不過它的XML腳本編寫格式讓XML文件特別大曲稼。對(duì)工程構(gòu)建過程中的過程控制特別好
??Maven【JAVA】
? 項(xiàng)目對(duì)象模型,通過其描述信息來管理項(xiàng)目的構(gòu)建湖员,報(bào)告和文檔的軟件項(xiàng)目管理工具贫悄。它填補(bǔ)了Ant缺點(diǎn),Maven第一次支持了從網(wǎng)絡(luò)上下載的功能娘摔,仍然采用xml作為配置文件格式窄坦。Maven專注的是依賴管理,使用Java編寫凳寺。
**Gradle**
? 屬于結(jié)合以上兩個(gè)的優(yōu)點(diǎn)鸭津,它繼承了Ant的靈活和Maven的生命周期管理,它最后被google作為了Android御用管理工具读第。它最大的區(qū)別是不用XML作為配置文件格式曙博,采用了DSL格式,使得腳本更加簡(jiǎn)潔怜瞒。
? 目前市面上Ant比較老父泳,所以一般是一些比較傳統(tǒng)的軟件企業(yè)公司使用般哼,Maven使用Java編寫, 是當(dāng)下大多數(shù)互聯(lián)網(wǎng)公司會(huì)使用的一個(gè)構(gòu)建工具惠窄, 中文文檔也比較齊全, gradle是用groovy編寫蒸眠,目前比較新型的構(gòu)建工具一些初創(chuàng)互聯(lián)網(wǎng)公司會(huì)使用,以后會(huì)有很大的使用空間杆融。
? Maven為Java世界引入了一個(gè)新的依賴管理系統(tǒng)jar包管理 jar 升級(jí)時(shí)修改配置文件即可楞卡。在Java世界中,可以用groupId脾歇、artifactId蒋腮、version組成的Coordination(坐標(biāo))唯一標(biāo)識(shí)一個(gè)依賴。
? 任何基于Maven構(gòu)建的項(xiàng)目自身也必須定義這三項(xiàng)屬性藕各,生成的包可以是Jar包池摧,也可以是war包或者jar包。一個(gè)典型的依賴引用如下所示:
<dependency><groupId>javax.servlet</groupId>com.baidu<artifactId>javax.servlet-api</artifactId>ueditor echarts<version>3.1.0</version></dependency>
坐標(biāo)屬性的理解
? Maven坐標(biāo)為各種組件引入了秩序激况,任何一個(gè)組件都必須明確定義自己的坐標(biāo)作彤。
groupId
? 定義當(dāng)前Maven項(xiàng)目隸屬的實(shí)際項(xiàng)目-公司名稱。(jar包所在倉(cāng)庫(kù)路徑) 由于Maven中模塊的概念乌逐,因此一個(gè)實(shí)際項(xiàng)目往往會(huì)被劃分為很多模塊竭讳。 比如spring是一個(gè)實(shí)際項(xiàng)目,其對(duì)應(yīng)的Maven模塊會(huì)有很多浙踢,如spring-core,spring-webmvc等绢慢。
artifactId
? 該元素定義實(shí)際項(xiàng)目中的一個(gè)Maven模塊-項(xiàng)目名, 推薦的做法是使用實(shí)際項(xiàng)目名稱作為artifactId的前綴成黄。 比如: spring-bean呐芥、 spring-webmvc等逻杖。
version
? 該元素定義Maven項(xiàng)目當(dāng)前所處的版本奋岁。
? 項(xiàng)目復(fù)查時(shí) dao service controller 層分離將一個(gè)項(xiàng)目分解為多個(gè)模塊已經(jīng)是很通用的一種方式。
? 在Maven中需要定義一個(gè)parent POM作為一組module的聚合POM荸百。在該P(yáng)OM中可以使用 標(biāo)簽來定義一組子模塊闻伶。parent POM不會(huì)有什么實(shí)際構(gòu)建產(chǎn)出。而parent POM中的build配置以及依賴配置都會(huì)自動(dòng)繼承給子module够话。
? Ant時(shí)代大家創(chuàng)建Java項(xiàng)目目錄時(shí)比較隨意蓝翰,然后通過Ant配置指定哪些屬于source,那些屬于testSource等女嘲。而Maven在設(shè)計(jì)之初的理念就是Conversion over configuration(約定大于配置)畜份。其制定了一套項(xiàng)目目錄結(jié)構(gòu)作為標(biāo)準(zhǔn)的Java項(xiàng)目結(jié)構(gòu),解決不同ide 帶來的文件目錄不一致問題。
<plugin><groupId>org.mortbay.jetty</groupId><artifactId>maven-jetty-plugin</artifactId><version>6.1.25</version><configuration><scanIntervalSeconds>10</scanIntervalSeconds><contextPath>/test</contextPath></configuration></plugin>
? JDK版本1.7及以上版本
? 下載地址:http://maven.apache.org/download.html
? 解壓后把Maven的根目錄配置到系統(tǒng)環(huán)境變量中MAVEN_HOME欣尼,將bin目錄配置到path變量中爆雹。
? 注:maven解壓后存放的目錄不要包含中文和空格
? 打開dos窗口停蕉,執(zhí)行 mvn -v
認(rèn)識(shí)Maven目錄結(jié)構(gòu)
??Maven項(xiàng)目目錄結(jié)構(gòu)
任務(wù):手動(dòng)創(chuàng)建一個(gè)Maven項(xiàng)目,并編譯運(yùn)行成功钙态!
創(chuàng)建一個(gè)文件夾作為項(xiàng)目的根目錄
在根目錄中創(chuàng)建一個(gè)pom.xml文件慧起,內(nèi)容如下
<?xml version="1.0" encoding="utf-8"?><projectxmlns="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.xxxx</groupId><artifactId>maven01</artifactId><version>0.0.1-SNAPSHOT</version><packaging>jar</packaging><name>maven01</name><url>http://maven.apache.org</url><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><dependencies><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>3.8.1</version><scope>test</scope></dependency></dependencies></project>
Ps:標(biāo)簽定義解釋
根目錄下的第一個(gè)子元素 ModelVersion指定當(dāng)前Pom模型的版本,對(duì)于Maven3來說册倒,它只能是4.0.0 蚓挤。指定了當(dāng)前Maven模型的版本號(hào),對(duì)于Maven2和Maven3來說驻子,它只能是4.0.0
groupId定義了項(xiàng)目屬于哪個(gè)組灿意, 這個(gè)組往往和項(xiàng)目所在的組織和公司存在關(guān)聯(lián)。
比如: com.xxxx
artifactId 定義了當(dāng)前Maven項(xiàng)目在組中唯一的ID崇呵。
Version? X.X.X-里程碑
比如:1.0.0-SNAPSHOT? ?
第一個(gè)X 大版本 有重大變革
第二個(gè)X 小版本? 修復(fù)bug洒琢,增加功能
第三個(gè)X 更新
里程碑版本:
SNAPSHOT (快照崖疤,開發(fā)版)
alpha(內(nèi)部測(cè)試)
beta(公開測(cè)試)
Release | RC( 發(fā)布版)
GA(正常版本)
使用name標(biāo)簽聲明一個(gè)對(duì)于用戶更為友好的項(xiàng)目名稱,雖然不是必須的,但還是推薦為每個(gè)Pom聲明name掐暮,以方便信息交流。
packagecom.xxxx.demo;publicclassHello{publicstaticvoidmain(String[]args){System.out.println("hello maven");}}
? cmd下面斟赚,進(jìn)入項(xiàng)目的根目錄
? 1. 編譯java文件
? mvn compile
? 2. 執(zhí)行main 方法
? mvn exec:java -Dexec.mainClass=“com.xxxx.demo.Hello”
??注:第一次下載會(huì)比較慢废菱,要修改maven解壓之后的conf目錄下的settings.xml。
1.1.修改默認(rèn)倉(cāng)庫(kù)位置打開maven目錄 -> conf -> settings.xml添加倉(cāng)庫(kù)位置配置<localRepository>F:/m2/repository</localRepository>注:倉(cāng)庫(kù)位置改為自己本機(jī)的指定目錄化漆,"/"不要寫反1.2.更換阿里鏡像,加快依賴下載<mirror><id>nexus-aliyun</id><mirrorOf>central</mirrorOf><name>Nexus aliyun</name><url>http://maven.aliyun.com/nexus/content/groups/public</url></mirror>
如果編譯不成功估脆,可能出現(xiàn)的問題
1. 不是使用管理員權(quán)限執(zhí)行dos命令
2. JDK環(huán)境配置有問題,重裝JDK
3. 代碼編寫時(shí)座云,類里面沒設(shè)置包名(如果編譯時(shí)類沒加包名疙赠,執(zhí)行時(shí)也不需要加包名)
? 作為開發(fā)利器的maven,為我們提供了十分豐富的命令朦拖,了解maven的命令行操作并熟練運(yùn)用常見的maven命令還是十分必要的圃阳,即使譬如IDEA等工具給我提供了圖形界面化工具,但其底層還是依靠maven命令來驅(qū)動(dòng)的璧帝。
Maven的命令格式如下:
mvn[plugin-name]:[goal-name]
命令代表的含義:執(zhí)行plugin-name插件的goal-name目標(biāo)
命令描述
mvn –version顯示版本信息
mvn clean清理項(xiàng)目生產(chǎn)的臨時(shí)文件,一般是模塊下的target目錄
mvn compile編譯源代碼捍岳,一般編譯模塊下的src/main/java目錄
mvn package項(xiàng)目打包工具,會(huì)在模塊下的target目錄生成jar或war等文件
mvn test測(cè)試命令,或執(zhí)行src/test/java/下junit的測(cè)試用例.
mvn install將打包的jar/war文件復(fù)制到你的本地倉(cāng)庫(kù)中,供其他模塊使用
mvn deploy將打包的文件發(fā)布到遠(yuǎn)程參考,提供其他人員進(jìn)行下載依賴
mvn site生成項(xiàng)目相關(guān)信息的網(wǎng)站
mvn eclipse:eclipse將項(xiàng)目轉(zhuǎn)化為Eclipse項(xiàng)目
mvn dependency:tree打印出項(xiàng)目的整個(gè)依賴樹
mvn archetype:generate創(chuàng)建Maven的普通java項(xiàng)目
mvn tomcat7:run在tomcat容器中運(yùn)行web應(yīng)用
mvn jetty:run調(diào)用 Jetty 插件的 Run 目標(biāo)在 Jetty Servlet 容器中啟動(dòng) web 應(yīng)用
注意:運(yùn)行maven命令的時(shí)候,首先需要定位到maven項(xiàng)目的目錄睬隶,也就是項(xiàng)目的pom.xml文件所在的目錄锣夹。否則,必以通過參數(shù)來指定項(xiàng)目的目錄苏潜。
? 上面列舉的只是比較通用的命令银萍,其實(shí)很多命令都可以攜帶參數(shù)以執(zhí)行更精準(zhǔn)的任務(wù)。
例如:
mvn package -Dmaven.test.skip=true
? 以-D開頭恤左,將maven.test.skip的值設(shè)為true,就是告訴maven打包的時(shí)候跳過單元測(cè)試贴唇。同理贰锁,mvn deploy-Dmaven.test.skip=true代表部署項(xiàng)目并跳過單元測(cè)試。
? 比如項(xiàng)目開發(fā)需要有多個(gè)環(huán)境滤蝠,一般為開發(fā)豌熄,測(cè)試,預(yù)發(fā)物咳,正式4個(gè)環(huán)境锣险,在pom.xml中的配置如下:
<profiles><profile><id>dev</id><properties><env>dev</env></properties><activation><activeByDefault>true</activeByDefault></activation></profile><profile><id>qa</id><properties><env>qa</env></properties></profile><profile><id>pre</id><properties><env>pre</env></properties></profile><profile><id>prod</id><properties><env>prod</env></properties></profile></profiles>......<build><filters><filter>config/${env}.properties</filter></filters><resources><resource><directory>src/main/resources</directory><filtering>true</filtering></resource></resources>......</build>
??profiles定義了各個(gè)環(huán)境的變量id,filters中定義了變量配置文件的地址览闰,其中地址中的環(huán)境變量就是上面profile中定義的值芯肤,resources中是定義哪些目錄下的文件會(huì)被配置文件中定義的變量替換。
? 通過maven可以實(shí)現(xiàn)按不同環(huán)境進(jìn)行打包部署压鉴,例如:
??mvn package -Pdev -Dmaven.test.skip=true
? 表示打包本地環(huán)境崖咨,并跳過單元測(cè)試
選擇 “File” —> “Other Settings” —> “Settings for New Projects…” —> 搜索 “Maven”
選擇下載好的maven版本(目錄選到bin目錄的上一級(jí)目錄)
設(shè)置settings.xml文件
設(shè)置好之后,選擇 “Apply” 或者 “OK”
選擇 “File” —> “New” —> “Project”
選擇"Maven"油吭,設(shè)置JDK版本击蹲,選擇maven項(xiàng)目的模板
設(shè)置項(xiàng)目的 GroupId 和 ArtifactId
檢查Maven環(huán)境,選擇 “Next”
檢查項(xiàng)目名和工作空間婉宰,選擇 “Finish”
等待項(xiàng)目創(chuàng)建歌豺,下載資源,創(chuàng)建完成后目錄結(jié)構(gòu)如下
注:右下角彈出的提示框心包,選擇 “Enable Auto-Import”(Maven啟動(dòng)自動(dòng)導(dǎo)入)
點(diǎn)擊右上角的 "Add Configurations "类咧,打開 “Run/Debug Configurations” 窗口
點(diǎn)擊左上角的 “+” 號(hào),選擇 “Maven”
設(shè)置編譯項(xiàng)目的命令
執(zhí)行編譯命令蟹腾,兩個(gè)圖標(biāo)分別代表"普通模式"和"調(diào)試模式"
編譯成功
創(chuàng)建Web項(xiàng)目與創(chuàng)建Java項(xiàng)目步驟基本一致痕惋,區(qū)別在于選擇 Maven模板(web項(xiàng)目選擇webapp),如圖:
注:其他步驟與創(chuàng)建普通的Java項(xiàng)目相同娃殖。
項(xiàng)目目錄結(jié)構(gòu)如下:
<!-- JDN的版本修改為1.8 --><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><maven.compiler.source>1.8</maven.compiler.source><maven.compiler.target>1.8</maven.compiler.target></properties>
<!-- junit的版本修改為4.12 --><dependencies><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><scope>test</scope></dependency></dependencies>
<!-- 將這個(gè)標(biāo)簽及標(biāo)簽中的內(nèi)容全部刪除 --><pluginManagement>...</pluginManagement>
? 在 build 標(biāo)簽中添加 plugins 標(biāo)簽
Jetty插件
<!-- 設(shè)置在plugins標(biāo)簽中 --><plugin><groupId>org.mortbay.jetty</groupId><artifactId>maven-jetty-plugin</artifactId><version>6.1.25</version><configuration><!-- 熱部署值戳,每10秒掃描一次 --><scanIntervalSeconds>10</scanIntervalSeconds><!-- 可指定當(dāng)前項(xiàng)目的站點(diǎn)名 --><contextPath>/test</contextPath><connectors><connectorimplementation="org.mortbay.jetty.nio.SelectChannelConnector"><port>9090</port><!-- 設(shè)置啟動(dòng)的端口號(hào) --></connector></connectors></configuration></plugin>
Tomcat插件
<!-- 設(shè)置在plugins標(biāo)簽中 --><plugin><groupId>org.apache.tomcat.maven</groupId><artifactId>tomcat7-maven-plugin</artifactId><version>2.1</version><configuration><port>8081</port><!-- 啟動(dòng)端口 默認(rèn):8080 --><path>/test</path><!-- 項(xiàng)目的站點(diǎn)名,即對(duì)外訪問路徑 --><uriEncoding>UTF-8</uriEncoding><!-- 字符集編碼 默認(rèn):ISO-8859-1 --><server>tomcat7</server><!-- 服務(wù)器名稱 --></configuration></plugin>
點(diǎn)擊右上角的 "Add Configurations "珊随,打開 “Run/Debug Configurations” 窗口
點(diǎn)擊左上角的 “+” 號(hào)述寡,選擇 “Maven”
Jetty插件配置
也可以輸入命令指定端口啟動(dòng)
jetty:run -Djetty.port=9090# 需要將插件配置中的port標(biāo)簽去掉
點(diǎn)擊啟動(dòng)圖標(biāo)柿隙,啟動(dòng)服務(wù)
啟動(dòng)成功
瀏覽器訪問效果
Tomcat插件配置
啟動(dòng)方式如上叶洞,啟動(dòng)成功
瀏覽器訪問 http://localhost:8080/test
Maven依賴倉(cāng)庫(kù):
? https://mvnrepository.com/
Tomcat7插件的命令:
? https://tomcat.apache.org/maven-plugin-trunk/tomcat7-maven-plugin/plugin-info.html
? 當(dāng)?shù)谝淮芜\(yùn)行Maven命令的時(shí)候, 你需要Internet鏈接禀崖, 因?yàn)樗枰獜木W(wǎng)上下載一些文件衩辟。 那么它從哪里下載呢? 它是從Maven默認(rèn)的遠(yuǎn)程庫(kù)下載的波附。 這個(gè)遠(yuǎn)程倉(cāng)庫(kù)有Maven的核心插件和可供下載的jar文件艺晴。
? 對(duì)于Maven來說昼钻, 倉(cāng)庫(kù)只分為兩類:?本地倉(cāng)庫(kù)和遠(yuǎn)程倉(cāng)庫(kù)。
? 當(dāng)Maven根據(jù)坐標(biāo)尋找構(gòu)件的時(shí)候封寞,它首先會(huì)查看本地倉(cāng)庫(kù)然评,如果本地倉(cāng)庫(kù)存在,則直接使用狈究; 如果本地沒有碗淌,Maven就會(huì)去遠(yuǎn)程倉(cāng)庫(kù)查找,發(fā)現(xiàn)需要的構(gòu)件之后抖锥,下載到本地倉(cāng)庫(kù)再使用亿眠。 如果本地倉(cāng)庫(kù)和遠(yuǎn)程倉(cāng)庫(kù)都沒有,Maven就會(huì)報(bào)錯(cuò)磅废。
? 遠(yuǎn)程倉(cāng)庫(kù)分為三種: 中央倉(cāng)庫(kù)纳像,私服, 其他公共庫(kù)拯勉。
? 中央倉(cāng)庫(kù)是默認(rèn)配置下竟趾,Maven下載jar包的地方。
? 私服是另一種特殊的遠(yuǎn)程倉(cāng)庫(kù)宫峦,為了節(jié)省帶寬和時(shí)間潭兽,應(yīng)該在局域網(wǎng)內(nèi)架設(shè)一個(gè)私有的倉(cāng)庫(kù)服務(wù)器,用其代理所有外部的遠(yuǎn)程倉(cāng)庫(kù)斗遏。 內(nèi)部的項(xiàng)目還能部署到私服上供其他項(xiàng)目使用山卦。
? 一般來說,在Maven項(xiàng)目目錄下诵次,沒有諸如lib/這樣用來存放依賴文件的目錄账蓉。 當(dāng)Maven在執(zhí)行編譯或測(cè)試時(shí),如果需要使用依賴文件逾一,它總是基于坐標(biāo)使用本地倉(cāng)庫(kù)的依賴文件铸本。
? 默認(rèn)情況下, 每個(gè)用戶在自己的用戶目錄下都有一個(gè)路徑名為.m2/repository/的倉(cāng)庫(kù)目錄遵堵。 有時(shí)候箱玷,因?yàn)槟承┰颍ū热鏲盤空間不足),需要修改本地倉(cāng)庫(kù)目錄地址。
? 對(duì)于倉(cāng)庫(kù)路徑的修改陌宿,可以通過maven 配置文件conf 目錄下settings.xml來指定倉(cāng)庫(kù)路徑
<!-- 設(shè)置到指定目錄中锡足,路徑的斜桿不要寫反 --><settings><localRepository>D:/m2/repository</localRepository></settings>
? 由于原始的本地倉(cāng)庫(kù)是空的,maven必須知道至少一個(gè)可用的遠(yuǎn)程倉(cāng)庫(kù)壳坪,才能執(zhí)行maven命令的時(shí)候下載到需要的構(gòu)件舶得。中央倉(cāng)庫(kù)就是這樣一個(gè)默認(rèn)的遠(yuǎn)程倉(cāng)庫(kù)。
? maven-model-builder-3.3.9.jar maven自動(dòng)的 jar 中包含了一個(gè) 超級(jí)POM爽蝴。定義了默認(rèn)中央倉(cāng)庫(kù)的位置沐批。
中央倉(cāng)庫(kù)包含了2000多個(gè)開源項(xiàng)目纫骑,接收每天1億次以上的訪問。
? 私服是一種特殊的遠(yuǎn)程倉(cāng)庫(kù)九孩,它是架設(shè)在局域網(wǎng)內(nèi)的倉(cāng)庫(kù)服務(wù)先馆, 私服代理廣域網(wǎng)上的遠(yuǎn)程倉(cāng)庫(kù),供局域網(wǎng)內(nèi)的maven用戶使用躺彬。 當(dāng)maven需要下載構(gòu)件時(shí)磨隘, 它去私服當(dāng)中找,如果私服沒有顾患, 則從外部遠(yuǎn)程倉(cāng)庫(kù)下載番捂,并緩存在私服上, 再為maven提供江解。
? 此外设预,一些無法從外部倉(cāng)庫(kù)下載的構(gòu)件也能從本地上傳到私服提供局域網(wǎng)中其他人使用
配置方式項(xiàng)目pom.xml 配置
<repositories><repository><snapshots><enabled>true</enabled></snapshots><id>public</id><name>Public Repositories</name><url>http://192.168.0.96:8081/content/groups/public/</url></repository><repository><id>getui-nexus</id><url>http://mvn.gt.igexin.com/nexus/content/repositories/releases/</url></repository></repositories>
公司內(nèi)部應(yīng)該建立私服:
節(jié)省自己的外網(wǎng)帶寬
加速maven構(gòu)建
部署第三方控件
提高穩(wěn)定性
降低中央倉(cāng)庫(kù)的負(fù)荷
常用的阿里云倉(cāng)庫(kù)配置
<mirror><id>nexus-aliyun</id><mirrorOf>central</mirrorOf><name>Nexus aliyun</name><url>http://maven.aliyun.com/nexus/content/groups/public</url></mirror>
Maven環(huán)境下構(gòu)建多模塊項(xiàng)目
? 使用maven 提供的多模塊構(gòu)建的特性完成maven 環(huán)境下多個(gè)模塊的項(xiàng)目的管理與構(gòu)建。
這里以四個(gè)模塊為例來搭建項(xiàng)目,以達(dá)到通俗易懂的初衷
模塊 maven_parent —– 基模塊,就是常說的parent (pom)
模塊 maven_dao —–? 數(shù)據(jù)庫(kù)的訪問層犁河,例如jdbc操作(jar)
模塊 maven_service —– 項(xiàng)目的業(yè)務(wù)邏輯層 (jar)
模塊 maven_controller —– 用來接收請(qǐng)求鳖枕,響應(yīng)數(shù)據(jù) (war)
創(chuàng)建 maven_parent 項(xiàng)目
選擇 File —> Settings —> Project
設(shè)置 GroupId 和 ArtifactId
設(shè)置項(xiàng)目名稱及工作空間
選擇項(xiàng)目maven_parent,右鍵選擇 New 桨螺,選擇Module
選擇Maven項(xiàng)目的模板(普通 Java 項(xiàng)目)
設(shè)置子模塊的的 ArtifactId
設(shè)置Maven的配置
設(shè)置子模塊的名稱及存放位置
? 創(chuàng)建 maven_service 模塊的步驟與 maven_dao模塊一致宾符。
? 創(chuàng)建 maven_service 模塊的步驟與 maven_dao模塊基本一致,只需要將第一步選擇Maven模板設(shè)置為web項(xiàng)目即可灭翔。(模板類型:maven-archetype-webapp)
? 模塊全部創(chuàng)建完畢后魏烫,效果如下:
設(shè)置 JDK 版本
單元測(cè)試 JUnit版本
刪除多余的配置
新建包
在包中創(chuàng)建 UserDao類
在類中添加方法
packagecom.xxxx.dao;publicclassUserDao{publicstaticvoidtestDao(){System.out.println("UserDao Test...");}}
添加maven_dao的依賴
<!-- 加入maven_dao模塊的依賴 --><dependency><groupId>com.xxxx</groupId><artifactId>maven_dao</artifactId><version>1.0-SNAPSHOT</version></dependency>
在項(xiàng)目中添加UserService類,并添加方法
packagecom.xxxx.service;importcom.xxxx.dao.UserDao;publicclassUserService{publicstaticvoidtestService(){System.out.println("UserService Test...");// 調(diào)用UserDao的方法UserDao.testDao();}}
添加 maven_service 模塊的依賴
<!-- 加入maven_service模塊的依賴 --><dependency><groupId>com.xxxx</groupId><artifactId>maven_service</artifactId><version>1.0-SNAPSHOT</version></dependency>
添加Servlet的依賴
<!-- Servlet的依賴 --><dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>3.0.1</version><scope>provided</scope></dependency>
新建 Java 類肝箱,繼承 HttpServlet 類哄褒,并重寫 service方法
packagecom.xxxx.controller;importcom.xxxx.service.UserService;importjavax.servlet.ServletException;importjavax.servlet.annotation.WebServlet;importjavax.servlet.http.HttpServlet;importjavax.servlet.http.HttpServletRequest;importjavax.servlet.http.HttpServletResponse;importjava.io.IOException;@WebServlet("/user")publicclassUserServletextendsHttpServlet{@Overrideprotectedvoidservice(HttpServletRequest req,HttpServletResponse resp)throwsServletException,IOException{System.out.println("UserServlet Test...");// 調(diào)用UserService層的方法UserService.testService();}}
添加Tomcat插件
<!-- 添加插件 --><plugins><!-- tomcat7插件 --><plugin><groupId>org.apache.tomcat.maven</groupId><artifactId>tomcat7-maven-plugin</artifactId><version>2.1</version><configuration><!-- <port>8080</port> --><path>/web</path><uriEncoding>UTF-8</uriEncoding><server>tomcat7</server></configuration></plugin></plugins>
啟動(dòng)項(xiàng)目
訪問項(xiàng)目
訪問地址:http://localhost:8080/web/user
訪問結(jié)果:
如果啟動(dòng)失敗,請(qǐng)先將父項(xiàng)目 install
注:如果父項(xiàng)目 install 失敗煌张,則先將所有子模塊 install 成功后呐赡,再 install 父項(xiàng)目。
? 對(duì)于企業(yè)級(jí)項(xiàng)目骏融,無論是進(jìn)行本地測(cè)試链嘀,還是測(cè)試環(huán)境測(cè)試以及最終的項(xiàng)目上線,都會(huì)涉及項(xiàng)目的打包操作档玻。對(duì)于每個(gè)環(huán)境下的項(xiàng)目打包怀泊,對(duì)應(yīng)的項(xiàng)目所需要的配置資源都會(huì)有所區(qū)別,實(shí)現(xiàn)打包的方式有很多種窃肠,可以通過ant包个,或者通過idea 自帶的打包功能實(shí)現(xiàn)項(xiàng)目打包,但當(dāng)項(xiàng)目很大并且需要的外界配置很多時(shí)冤留,此時(shí)打包的配置就會(huì)異常復(fù)雜碧囊,對(duì)于maven 項(xiàng)目,我們可以用過 pom.xml 配置的方式來實(shí)現(xiàn)打包時(shí)的環(huán)境選擇纤怒,相比較其他形式打包工具糯而,通過maven 只需要通過簡(jiǎn)單的配置,就可以輕松完成不同環(huán)境下項(xiàng)目的整體打包泊窘。
? 比如下面這樣一個(gè)項(xiàng)目熄驼,項(xiàng)目中配置了不同環(huán)境下項(xiàng)目所需要的配置文件,這時(shí)候需要完成不同環(huán)境下的打包操作烘豹,此時(shí)通過修改pom.xml 如下:
建立對(duì)應(yīng)的目錄結(jié)構(gòu)
? 使用idea創(chuàng)建項(xiàng)目瓜贾,目錄結(jié)構(gòu)可能會(huì)缺失,需要通過手動(dòng)添加對(duì)應(yīng)的目錄携悯。
添加 Java 源文件夾
選擇項(xiàng)目的 main 文件夾祭芦,右鍵選擇New,選擇Directory
輸入文件夾名 “Java”憔鬼,如圖:
選擇 java 目錄龟劲,右鍵選擇 Mark Directory as,選擇 Sources Root轴或。將文件夾標(biāo)記為源文件夾昌跌。
添加資源文件夾
步驟如上,創(chuàng)建文件夾照雁,命名為 resources蚕愤,并標(biāo)記為 Resources Root
添加對(duì)應(yīng)的文件夾目錄,及添加不同環(huán)境下對(duì)應(yīng)的配置文件饺蚊。(本地環(huán)境审胸、測(cè)試環(huán)境、正式環(huán)境)
<!-- 打包環(huán)境配置 開發(fā)環(huán)境 測(cè)試環(huán)境 正式環(huán)境 --><profiles><profile><id>dev</id><properties><env>dev</env></properties><!-- 未指定環(huán)境時(shí)卸勺,默認(rèn)打包dev環(huán)境 --><activation><activeByDefault>true</activeByDefault></activation></profile><profile><id>test</id><properties><env>test</env></properties></profile><profile><id>product</id><properties><env>product</env></properties></profile></profiles>
<!-- 對(duì)于項(xiàng)目資源文件的配置放在build中 --><resources><resource><directory>src/main/resources/${env}</directory></resource><resource><directory>src/main/java</directory><includes><include>**/*.xml</include><include>**/*.properties</include><include>**/*.tld</include></includes><filtering>false</filtering></resource></resources>
打開Run/Debug Configuarations窗口砂沛,輸入對(duì)應(yīng)的打包命令
此時(shí)對(duì)應(yīng)打包命令
1. `clean compile package -Dmaven.test.skip=true`
? 打包默認(rèn)環(huán)境(開發(fā)環(huán)境)并且跳過maven 測(cè)試操作
2. `clean compile package -Ptest -Dmaven.test.skip=true`
? 打包測(cè)試環(huán)境并且跳過maven 測(cè)試操作
3. `clean compile package -Pproduct -Dmaven.test.skip=true`
? 打包生產(chǎn)環(huán)境并且跳過maven 測(cè)試操作
打包成功
不同的項(xiàng)目打包的文件不一樣,一般來說曙求,普通java項(xiàng)目打成jar包碍庵,web項(xiàng)目打成war包
? 根元素project下的dependencies可以包含多個(gè) dependence元素,以聲明多個(gè)依賴悟狱。每個(gè)依賴都應(yīng)該包含以下元素:
groupId, artifactId, version : 依賴的基本坐標(biāo)静浴, 對(duì)于任何一個(gè)依賴來說,基本坐標(biāo)是最重要的挤渐, Maven根據(jù)坐標(biāo)才能找到需要的依賴苹享。
Type: 依賴的類型,大部分情況下不需要聲明。 默認(rèn)值為jar
Scope: 依賴范圍(compile,test,provided,runtime,system)
compile: 編譯依賴范圍得问。
如果沒有指定囤攀,就會(huì)默認(rèn)使用該依賴范圍。使用此依賴范圍的Maven依賴宫纬,對(duì)于編譯焚挠、測(cè)試、運(yùn)行三種classpath都有效漓骚。
test: 測(cè)試依賴范圍蝌衔。
使用此依賴范圍的Maven依賴,只對(duì)于測(cè)試classpath有效蝌蹂,在編譯主代碼或者運(yùn)行項(xiàng)目的使用時(shí)將無法使用此類依賴噩斟。典型的例子就是JUnit,它只有在編譯測(cè)試代碼及運(yùn)行測(cè)試的時(shí)候才需要孤个。
provided: 已提供依賴范圍剃允。
使用此依賴范圍的Maven依賴,對(duì)于編譯和測(cè)試classpath有效硼身,但在運(yùn)行時(shí)無效硅急。典型的例子是servlet-api,編譯和測(cè)試項(xiàng)目的時(shí)候需要該依賴佳遂,但在運(yùn)行項(xiàng)目的時(shí)候营袜,由于容器已經(jīng)提供,就不需要Maven重復(fù)地引入一遍(如:servlet-api)丑罪。
runtime: 運(yùn)行時(shí)依賴范圍荚板。
使用此依賴范圍的Maven依賴,對(duì)于測(cè)試和運(yùn)行classpath有效吩屹,但在編譯主代碼時(shí)無效跪另。典型的例子是JDBC驅(qū)動(dòng)實(shí)現(xiàn),項(xiàng)目主代碼的編譯只需要JDK提供的JDBC接口煤搜,只有在執(zhí)行測(cè)試或者運(yùn)行項(xiàng)目的時(shí)候才需要實(shí)現(xiàn)上述接口的具體JDBC驅(qū)動(dòng)免绿。
system: 系統(tǒng)依賴范圍。
該依賴與三種classpath的關(guān)系擦盾,和provided依賴范圍完全一致嘲驾。但是,使用system范圍依賴時(shí)必須通過systemPath元素顯式地指定依賴文件的路徑迹卢。由于此類依賴不是通過Maven倉(cāng)庫(kù)解析的辽故,而且往往與本機(jī)系統(tǒng)綁定,可能造成構(gòu)建的不可移植腐碱,因此應(yīng)該謹(jǐn)慎使用誊垢。
Optional:標(biāo)記依賴是否可選
Exclusions: 用來排除傳遞性依賴。
? 首先需要知道,Maven在編譯項(xiàng)目主代碼的時(shí)候需要使用一套classpath喂走。 比如:編譯項(xiàng)目代碼的時(shí)候需要用到spring-core, 該文件以依賴的方式被引入到classpath中殃饿。 其次, Maven在執(zhí)行測(cè)試的時(shí)候會(huì)使用另外一套classpath缴啡。 如:junit壁晒。
? 最后在實(shí)際運(yùn)行項(xiàng)目時(shí)瓷们,又會(huì)使用一套classpath业栅, spring-core需要在該classpath中,而junit不需要谬晕。
? 那么依賴范圍就是用來控制依賴與這三種classpath(編譯classpath碘裕,測(cè)試classpath,運(yùn)行時(shí)classpath)的關(guān)系攒钳, Maven有以下幾種依賴范圍:
Compile 編譯依賴范圍帮孔。 如果沒有指定,就會(huì)默認(rèn)使用該依賴范圍不撑。 使用此依賴范圍的Maven依賴文兢, 對(duì)于編譯,測(cè)試焕檬,運(yùn)行都有效姆坚。
Test: 測(cè)試依賴范圍。 只在測(cè)試的時(shí)候需要实愚。比如junit
Provided: 已提供依賴范圍兼呵。 使用此依賴范圍的Maven依賴,對(duì)于編譯和測(cè)試有效腊敲, 但在運(yùn)行時(shí)無效击喂。 典型的例子是servlet-API, 編譯和測(cè)試項(xiàng)目的需要, 但在運(yùn)行項(xiàng)目時(shí)碰辅, 由于容器已經(jīng)提供懂昂, 就不需要Maven重復(fù)地引入一遍。
Runtime: 運(yùn)行時(shí)依賴范圍没宾。 使用此依賴范圍的Maven依賴凌彬,對(duì)于測(cè)試和運(yùn)行有效, 但在編譯代碼時(shí)無效榕吼。 典型的例子是:jdbc驅(qū)動(dòng)程序饿序, 項(xiàng)目主代碼的編譯只需要jdk提供的jdbc接口,只有在執(zhí)行測(cè)試或者運(yùn)行項(xiàng)目的時(shí)候才需要實(shí)現(xiàn)上述接口的具體jdbc驅(qū)動(dòng)羹蚣。
System: 系統(tǒng)依賴范圍原探。 一般不使用。
? 傳遞依賴機(jī)制, 讓我們?cè)谑褂媚硞€(gè)jar的時(shí)候就不用去考慮它依賴了什么咽弦。也不用擔(dān)心引入多余的依賴徒蟆。 Maven會(huì)解析各個(gè)直接依賴的POM,將那些必要的間接依賴型型,以傳遞性依賴的形式引入到當(dāng)前項(xiàng)目中段审。
??注意: 傳遞依賴有可能產(chǎn)生沖突!闹蒜!
沖突場(chǎng)景:
A-->B--->C (2.0)
A-->E--->C (1.0)
? 如果A下同時(shí)存在兩個(gè)不同version的C寺枉,沖突!1谅洹(選取同時(shí)適合A姥闪、B的版本)
<dependencies><dependency><groupId>A</groupId><artifactId>A</artifactId><version>xxx</version><exclusions><exclusion><groupId>C</groupId><artifactId>C</artifactId></exclusion></exclusions></dependency><dependency><groupId>B</groupId><artifactId>B</artifactId></dependency></dependencies>