Maven学习总结(14)——Maven 多模块项目如何分工?
2019獨角獸企業重金招聘Python工程師標準>>>
一、開場白
使用Maven有段時間了,只能感慨真是個好東西,讓我從傳統模式體會到了嚴謹、規范、敏捷、方便的特性。
如果你懂Maven或許看過Juven翻譯的《Maven權威指南》;
發個牢騷:由于Maven的出身問題導致學習曲線陡峭,所有有些人就開始說Maven不好用;原因有二:一是排斥Maven,二是沒有耐心和精下心來學習,引用老毛的話來提醒我說的那些人:
沒有調查就沒有發言權
到了Maven這里就是(適用于技術方面):
沒有深入學習也沒有發言權
如果Maven不好那么Spring、Hibernate這些大家經常使用的框架為什么還是從ant轉移到Maven?
如果Maven不好那么為什么國外大多數項目都在使用Maven呢?
原因自己考慮,我不廢話!我的這些話就是告誡那些信口雌黃的人。
二、多模塊布局概述
詳細屬性Maven的童鞋們都看過《Maven權威指南》,里面也講解如何搭建多模塊的Maven項目,但是那個畢竟是比較簡單的,在實際應用中就有點水土不服了;
后來又參考了Juven的一篇《Maven最佳實踐:劃分模塊》博文,相對權威指南來說介紹的比較詳細了,但是這還是不能滿足我真正在企業應用的需求,等你看完Juven的博文后再看看下面這個實際應用中的項目布局有什么異同:
Maven多模塊布局概圖
OK,現在應該看出來有什么不同了,我的項目結構比權威指南里面的介紹復雜、比Juven的那篇文章說的也復雜,接下來再看看這張圖片:
plexus-security項目結構
上面這張圖片是我在寫這篇文章的時候剛剛找到的:《按需構建多模塊,玩轉Maven反應堆》,和上面的Maven多模塊布局概圖對比一下是不是基本一樣?真是后悔當初怎么沒有看到Juven的這篇文章,后來把hibernate的項目checkout下來分析他的maven多模塊結構布局然后再結合實際應用得出的Maven多模塊布局概圖。
OK,現在你對多模塊布局有了初步的印象了,接下來才是重點,逐個擊破、逐個分析。
三、多模塊布局詳解
無圖無真相,有圖才給力:(如果想真正了解多模塊那么請先看著圖片和說明揣摩一下含義……)
Maven多模塊布局概述圖
聲明:由于是本例是根據實際應用的項目來分析的,所以會比之前說的教程和Juven的文章實例復雜一些。
denong-pb:先看實例pom.xml:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | <?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/maven-v4_0_0.xsd" >?? ?? <modelVersion> 4.0 . 0 </modelVersion>?? ?? <groupId>com.wsria</groupId>?? ?? <artifactId>dn-pb</artifactId>?? ?? <version> 1.0 . 5 -SNAPSHOT</version>?? ?? <name>Denong?Point?Bank</name>?? ?? <packaging>pom</packaging>?? ?? <!--?設定團隊持續集成發布包服務器??-->?? ?? <distributionManagement>? ???? <repository>? ?????? <id>nexus</id>?? ?????? <name>Team?Nexus?Release?Repository</name>?? ?????? <url>http: //192.168.1.111:8081/nexus/content/repositories/releases</url>? ???? </repository>?? ???? <snapshotRepository>? ?????? <id>nexus</id>?? ?????? <name>Team?Nexus?Snapshot?Repository</name>?? ?????? <url>http: //192.168.1.111:8081/nexus/content/repositories/snapshots</url>?? ?????? <uniqueVersion> false </uniqueVersion>? ???? </snapshotRepository>? ?? </distributionManagement>?? ?? <scm>? ???? <connection>scm:svn:https: //192.168.1.111:8443/svn/denong/pb/trunk</connection>?? ???? <url>https: //192.168.1.111:8443/svn/denong/pb/trunk</url>? ?? </scm>?? ?? <modules>? ???? <module>parent</module>?? ???? <module>common</module>?? ???? <module>entity</module>?? ???? <module>data</module>?? ???? <module>dao</module>?? ???? <module>service</module>?? ???? <module>web-parent</module>?? ???? <module>web-admin</module>?? ???? <module>web-site</module>? ?? </modules>?? ?? <build>? ???? <defaultGoal>install</defaultGoal>?? ???? <plugins>? ?????? <plugin>? ???????? <groupId>org.apache.maven.plugins</groupId>?? ???????? <artifactId>maven-release-plugin</artifactId>?? ???????? <version> 2.0 -beta- 9 </version>?? ???????? <configuration>? ?????????? <autoVersionSubmodules> true </autoVersionSubmodules>? ???????? </configuration>? ?????? </plugin>? ???? </plugins>? ?? </build>? </project> |
bin:可有可無,存放一些maven的命令批處理文件或者快捷bat文件,比如本地install項目或者打包根據產品profile(在模塊中配置id為product的profile)打包war;
common:估計有一些經驗的人都會把一些常用的工具類封裝起來,由經驗豐富的人來維護到common模塊中作為技術沉淀和公司的公共類庫,方便大家快速開發使用。當然實際應用中可能會使用公司已經存在的common模塊,然后單個項目中可能會再加入一個common模塊,一般公司的common包都是這么積累下來的;
dao:每個模塊的數據存取類,因為本項目是根據springside基礎上構建的,所以都是繼承HibernateDao,如果涉及到大數據量或者存儲過程的調用會再加入相應的*JdbcDao;
data:
data模塊結構
,根據上圖介紹一下:除了data目錄外其他的配置文件都是在測試期間使用的,根據不同需求使用不同配置文件,例如一些不需要spring啟動時初始化的數據使用applicationContext-test-no-init-sql.xml,這個沒有什么規定,根據項目來設置;data目錄是存放一些使用dbunit導出的xml數據文件,作用是在單元測試時的數據初始化或者利用數據文件初始化指定的數據庫,一般這些數據文件的類型包括:數據字典、系統配置參數等
entity:這里說一下JPA注解的實體工具,開始我使用的是eclipse3.6的JPA工具,但是發現有些屬性加不上@Column注解很是郁悶,只能手動加入;當然你也可以使用springside中提供的hibernatetools模板生成,但是我還是希望在生成期間能完全受控,所以最好想到了MyEclipse,配置好數據源然后從數據庫中逆向生成JPA,所有字段都正確配置;
parent:這里著重介紹一下,此模塊是所有子模塊需要繼承的超級POM,舉個例子容易理解:把本項目(denong-pb)當做是Java語言,那么parent模塊就是Object類,此模塊只負責定影其他子模塊需要使用的一些公共設置,謹記:
parent不負責管理子模塊,只是被子模塊集成,千萬不要和denong-pb目錄的pom.xml混淆
service:就是業務處理類,供web模塊調用;
web-parent:供web*模塊繼承,例如前后臺都需要調用的Action接口,像數據字典、地區信息、系統屬性等
web-admin:系統的后臺管理程序,使用了struts2的convention插件;
web-site:系統網站部分,同樣使用了struts2的convention插件,集成單點登錄功能
四、模塊之間依賴關系
直觀教程圖片最給力:
五、和SVN的整合——maven-release-plugin
maven-release-plugin是經常使用的插件,這里簡單介紹一下,要點:
每個模塊的scm配置:
| 1 2 3 4 | <scm> <connection>scm:svn:https: //192.168.1.111:8443/svn/denong/pb/trunk/模塊名稱</connection> <url>https: //192.168.1.111:8443/svn/denong/pb/trunk/模塊名稱</url> </scm> |
上面的scm配置在每一個模塊中存在,因為每一個模塊再svn目錄中有單獨的目錄;
但是parent模塊有點不同,因為除了parent模塊其他子模塊需要繼承parent,如下代碼:
?| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | <?xml?version= "1.0" ?> <parent> ???? <groupId>com.wsria</groupId> ???? <artifactId>parent</artifactId> ???? <version> 1.0 . 5 -SNAPSHOT</version> ???? <relativePath>../parent/pom.xml</relativePath> </parent> <artifactId>dn-pb-entity</artifactId> <!--?release插件?--> <plugin> ???? <groupId>org.apache.maven.plugins</groupId> ???? <artifactId>maven-release-plugin</artifactId> ???? <version> 2.0 -beta- 9 </version> ???? <configuration> ???????? <tagBase>https: //192.168.1.111:8443/svn/denong/pb/tags/</tagBase> ???????? <username>${svn.name}</username> ???????? <password>${svn.pwd}</password> ???? </configuration> </plugin> |
本地的settings.xml中配置(替換${svn.name}和${svn.pwd},也就是svn提交時的用戶名和密碼):
?| 1 2 3 4 5 6 7 8 9 10 11 | <?xml?version= "1.0" ?> <settings>...? <profiles> ???? <profile> ???????? <id>denong-product</id> ???????? <properties> ???????????? <svn.name>kafeitu</svn.name> ???????????? <svn.pwd> 123456 </svn.pwd> ???????? </properties> ???? </profile> </profiles>...</settings> |
在denong-pb目錄中執行命令:
D:\wsria\projects\denong\denong-pb>mvn release:prepare -Pdenong-product
在svn中自動打的tag結構為:
接下來就可以執行命令:
D:\wsria\projects\denong\denong-pb>mvn release:perform
六、多模塊布局問題
如果你夠細心可能發現了上面出現了relativePath屬性,這個再多模塊的配置中經常遇到的問題,根據目前的案例來說子模塊和parent是同級的目錄,但是每個子模塊又都需要繼承parent模塊的一些配置,比如上面介紹的到common模塊會使用如下配置:
?| 1 2 3 4 5 6 | <parent> <groupId>com.wsria</groupId> <artifactId>parent</artifactId> <version> 1.0 . 5 -SNAPSHOT</version> </parent> <artifactId>common</artifactId> |
現在問題來了,在common模塊下執行命令:mvn compile,得到的結果中包含了警告信息:
[WARNING] ‘parent.relativePath’ points at com.wsria:dn-pb instead of com.wsria:dn-pb-parent, please verify your project structure @ line 4, column 10
意思是找不到dn-pb-parent這個模塊……因為maven不知道dn-pb-parent模塊存在的位置才會導致警告信息的出現,解決辦法是手動指定dn-pb-parent模塊的位置,所以最終的解決辦法是在parent標簽中加入:
<relativePath>../parent/pom.xml</relativePath>
這樣maven就知道繼承的parent的具體位置了,
relativePath默認值為../pom.xml,參考:http://maven.apache.org/ref/3.0/maven-model/maven.html
完整的parent繼承配置:
?| 1 2 3 4 5 6 7 | <parent> <groupId>com.wsria</groupId> <artifactId>dn-pb-parent</artifactId> <version> 1.0 . 5 -SNAPSHOT</version> <relativePath>../parent/pom.xml</relativePath> </parent> <artifactId>dn-pb-common</artifactId> |
現在運行mvn命令一切正常了;
記得每一個繼承parent模塊的子模塊都需要添加relativePath設置
七、多模塊開發期間Debug
一般我們在開發web模塊的時候會啟用tomcat或者jboss的debug模式來斷點調試應用,但是你會發現如果web模塊依賴了service模塊想進入service模塊debug但是eclipse卻告訴你找不到class的源碼,解決辦法:
把service模塊加入到Build Path的Project列表中
八、其他方案
如何布局是根據每一個項目組的安排定義的,比如
一個項目組分模塊開發的話或許不像本例一樣分模塊而是把每一層都集中在一個項目中
或許web模塊單獨一個子模塊,其他的entyty、dao、service集中在一個子模塊model中
怎么布局需要根據項目實際情況來定義,當然要考慮到單個子模塊的重復利用,例如service模塊在本例中被web-admin和web-site模塊使用,如果以后再加入webservice模塊那么webservice也要依賴,或許還有命令行(command)模塊也要依賴
九、總結
我的項目結構如下:
項目劃分為核心、輔助及視圖三大模塊,其中核心模塊按功能劃分為各個小模塊,視圖模塊主要是后端WEB和各前端WEB;
trade是整個父級模塊,trade-code是核心模塊的父級模塊,繼承trade模塊,trade-help是輔助模塊的父級模塊,繼承trade模塊,trade-view是視圖模塊的父級模塊,繼承trade模塊;
項目整個文件結構是樹型結構;
轉載于:https://my.oschina.net/zhanghaiyang/blog/606806
總結
以上是生活随笔為你收集整理的Maven学习总结(14)——Maven 多模块项目如何分工?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android之获取手机上的图片和视频缩
- 下一篇: 如何实现文字翻译,这个技巧你需要掌握