maven助力javaweb專案縱向和橫向切割
筆者在網上看到了太多使用maven進行多模組構建的文件,主要是對專案進行橫向切割為不同的模組,每個模組為一個單一maven module project,現以一個專案舉例,來說明其大致步驟;然後,通過對該專案進行縱向切割,說明其配置方式,並比較兩者之間異同點。
1.專案需求
某公司現在開發一個幼兒園管理系統(專案名稱:wo-baby)整個系統的子系統包結構大致如下:
com.qfedu.wo.common
:該包提供整個專案的公共工具類等通用功能
com.qfedu.wo.sys
:系統管理子系統完成整個系統許可權管理,包括如下子包
com.qfedu.wo.sys.controller
com.qfedu.wo.sys.service
com.qfedu.wo.sys.dao
com.qfedu.wo.sys.entity
com.qfedu.wo.baby
:幼兒園管理子系統,完成整個幼兒園管理功能,包括如下子包
com.qfedu.wo.baby.controller
com.qfedu.wo.baby.service
com.qfedu.wo.baby.dao
com.qfedu.wo.baby.entity
2.專案橫向切割,分模組構建
橫向切割就是按照專案的分層開發模型,對整個專案進行分模組構建,劃分模組如下:
整個專案劃分為5個子模組,如上圖所示,各子模組對應的包如下:
wo-common:com.qfedu.wo.common
wo-web:com.qfedu.wo.sys.controller/com.qfedu.wo.baby.controller
wo-service:com.qfedu.wo.sys.service/com.qfedu.wo.baby.service
wo-dao:com.qfedu.wo.sys.dao/com.qfedu.wo.baby.dao
wo-entity:com.qfedu.wo.sys.entity/com.qfedu.wo.baby.entity
首先,構建maven主專案wo-root,其pom.xml核心配置如下,打包方式設定為pom
<modelVersion>4.0.0</modelVersion>
<groupId>com.qfedu.wo</groupId>
<artifactId>wo-root</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
其次,分別在其下建立maven module project(wo-common/wo-web/wo-service/wo-dao/wo-entity),其pom.xml中的核心配置如下:
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.qfedu.wo</groupId>
<artifactId>wo-root</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>wo-web</artifactId>
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>com.qfedu.wo</groupId>
<artifactId>wo-common</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.qfedu.wo</groupId>
<artifactId>wo-service</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.qfedu.wo</groupId>
<artifactId>wo-entity</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
其中的關鍵點就是使用parent配置,繼承wo-root專案中的配置;同時,新增對其他子模組的依賴。
3.縱向切割,分模組構建
橫向切割中存在如下問題:
1.假如公司後續又有一專案,需要基於系統管理子系統開發,那麼就需要從上述多個模組中,單獨抽離系統管理的程式碼和頁面,明顯沒有實現專案的充分共享
2.而且,新的專案中所有的靜態資源(圖片、css樣式、js框架、專案通用的js程式碼等)都需要從之前的專案中重新拷貝一份,這樣明顯不是一個很好的方案
為了應對上述需求,現對整個專案進行縱向切割。
縱向切割是按照專案功能,對整個專案進行切割,劃分模組如下:
整個專案劃分為5個子模組,如上圖所示,各子模組對應的包如下:
wo-common:com.qfedu.wo.common
,普通java專案
wo-web:包含所有公共web專案的靜態資源,例如js框架、通用css樣式、公司通用的js程式碼等,web專案
wo-sys:com.qfedu.wo.sys
,web專案
wo-baby:com.qfedu.wo.baby
,web專案
wo-root配置及各子專案的大部分配置,和上節相同,不再贅述,現以wo-sys為例,說明不同之處。
首先,繼承父專案wo-root配置
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.qfedu.wo</groupId>
<artifactId>wo-root</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>wo-sys</artifactId>
<packaging>war</packaging>`
其次,新增對wo-web專案依賴,type為war,scope為runtime
<dependencies>
<dependency>
<groupId>com.qfedu.wo</groupId>
<artifactId>wo-common</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.qfedu.wo</groupId>
<artifactId>wo-web</artifactId>
<version>${project.version}</version>
<type>war</type>
<scope>runtime</scope>
</dependency>
...
</dependencies>
最後,需要配置maven-war-plugin外掛,在執行或者釋出的時候,從wo-web中拷貝靜態資源
<build>
<finalName>wo-sys</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<warSourceDirectory>src/main/webapp</warSourceDirectory>
<overlays>
<overlay>
<groupId>com.qfedu.wo</groupId>
<artifactId>wo-web</artifactId>
<excludes>
<exclude>WEB-INF/lib/*</exclude>
<exclude>WEB-INF/web.xml</exclude>
</excludes>
</overlay>
</overlays>
</configuration>
</plugin>
</plugins>
</build>
wo-baby模組的配置稍有不同,它除了在執行時需要拷貝所有wo-sys專案的靜態資源外,在編譯時還依賴於wo-sys模組的類,所以,對wo-sys的依賴有兩個,type分別為jar和war,具體依賴配置如下:
<dependencies>
<dependency>
<groupId>com.qfedu.wo</groupId>
<artifactId>wo-common</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.qfedu.wo</groupId>
<artifactId>wo-sys</artifactId>
<type>jar</type>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.qfedu.wo</groupId>
<artifactId>wo-sys</artifactId>
<version>${project.version}</version>
<type>war</type>
<scope>runtime</scope>
</dependency>
...
</dependencies>