Mavn 篇:寫一個自己的模板,快速搭建項目

爲什麼要使用 Maven Archetype

 每次我們要使用框架寫一個網站時,比如 SSM,我們總是需要手寫 applicationContenxt.xml,mybatis-config.xml 和 jdbc.properties 這些配置文件,每一次寫的時候都會發現它們是大同小異的,於是聰明的我們學會了建立一份模板,每次要使用時就複製粘貼。同樣的還有 controller,service,dao 這些目錄,我們乾脆建立一個網站模板,每次使用的時候就從這個模板複製出來一份,然後進行微調就可以使用了。這種方法一般來說是高效的(相比較從頭開始寫),但卻有許多繁瑣的問題。

一,包與代碼的結構

 比如我們建立了如下的模板結構,controller 這些包一般是要包含在一個父包中的,比如 com.tree.controller 之類的,而不是直接 controller。很容易,給它添加幾層目錄就可以了,如下:

你創建的模板創建項目後添加包
java
 |_ controller
 |_ service
 |_ dao
 |_ model
 |_ Main.java
java
 |_ com
   |_ tree
     |_ controller
     |_ service
     |_ dao
     |_ domain
     |_ Main.java
 但是問題來了,模板裏面包含有一個 Main.java,它實際的目錄結構改變了,但是它的 package 卻沒有變,本來這也沒有什麼問題的,只需要修改它的 package 字段就可以了,如下:
package com.tree;	//	爲 Main.java 添加 package
public class Main{
    public static void main(String args[]){
        System.out.println("hello world");
    }
}	

但是如果模板中的類不只一個呢,這種情況下你難道要爲每個類都手動修改 package 字段嗎,Are you kidding?

二,代碼中的某些屬性值

比如我們在 main/resources 下有一個 jdbc.properties,其中是關於數據源的配置,如下:

# jdbc.properties
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql:///demo?characterEncoding=utf-8
jdbc.username=root
jdbc.password=root

你在複製粘貼之後一樣要手動修改這些值,最起碼 jdbc.url 這個值是必須改的。
也許你是一個很小心的人,你覺得這種問題對你來說不大,但你有沒有想過,就只有我剛纔說的那些嗎?比如:

<!-- spring 尋找註解的路徑配置 -->
<context:component-scan base-package="com.tree.*"/>
<!-- mybatis 生成 mapper 的路徑配置 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"
		p:basePackage="com.tree.mapper"/>
...
...
...

需要你修改的東西太多了,就算你夠細心,但這也失去了意義,這已經和我們要的方便想去甚遠了。

 恩,總結來說,我們使用上述類型的模板,我們不僅需要給它添加父包,還要修改代碼中 N 多的屬性值,真是想想都心累。當然了,如果你不嫌麻煩,你完全可以自己寫一個類,根據實際需要動態加工你的模板,這樣你就不用手動修改那麼多東西了,這也是不難的。不過現在有一個通用的解決方案存在,建議還是不要造重複的輪子好。
 現在開始進入正題了,大家第一次使用 Maven 建立項目的時候應該使用過 maven-archetype-quickstart 或者是 maven-achetype-wepapp,Maven 提供了一個插件,讓我們可以建立自己的 archetype(原型,模板),其支持自定義變量設置,完全可以解決上面說的那些問題。那麼下面先來講解 maven 模板的結構


創建 Archetype

一,添加插件依賴
<!-- 創建模板的插件 -->
<plugin>
	<artifactId>maven-archetype-plugin</artifactId>
	<version>3.0.1</version>
</plugin>
<!-- 識別空目錄 -->
<!-- 不然如果你的模板裏含有空目錄,在編譯成 Archetype 的時候就會被忽略掉 -->
<plugin>
	<artifactId>maven-resources-plugin</artifactId>
	<configuration>
		<includeEmptyDirs>true</includeEmptyDirs>
	</configuration>
</plugin>
二,Archetype 的結構
對象 含義
pom.xml 建立模板的 pom,每個 Maven 項目都有的東西
src/main/resources/archetype-resources 模板的內容
src/main/resources/META-INF/maven/archetype-metadata.xml 模板的描述,變量等東西的配置

archetype-resources 用來存放模板的內容,裏面和一般的 Maven 工程是一樣的結構,我們可以根據自己的需求在裏面建立我們的模板。
在這裏插入圖片描述
archetype-metadata.xml 用來描述模板的變量,默認提供以下變量

${groupId},${artifactId},${version},${package}

前面三個變量是模板內容中 pom.xml 的座標,當使用模板時我們輸入的座標信息會注入到項目中。

<groupId>${groupId}</groupId>
<artifactId>${artifactId}</artifactId>
<version>${version}</version>

第四個變量,也就是 ${package},很好理解的,只要我們將其放在類的 package 字段中,初始化項目的時候,會被注入進去,其值默認和 ${groupId} 一樣。

package ${package}.dao;
public class BaseDao{
    public static void main(String args[]){
        System.out.println("hello world");
    }
}

除了上述變量外,我們還可以自定義變量,如 database,username,password 等,只需要使用 ${ } 括起來就行,如下:

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql:///${database}?characterEncoding=utf-8
jdbc.username=${username}
jdbc.password=${password}

這樣只要我們建立項目之後設置這些字段,我們就不用再手動去修改這些屬性了。
${ } 這個符號我們也常用,你可能會擔心衝突問題。但請放心,這是不會的,因爲 Archetype 插件只會對 被過濾的 並且 定義過的 變量進行修改。這是什麼意思呢?一切的答案都在 archetype-metadata.xml 這個文件中,先來看看其結構。

archetype-descriptor (name)
    |_ fileSets
        |_ fileSet (filtered,packaged) -- 被過濾的
            |_ directory
            |_ includes
                |_ include
            |_ excludes
                |_ exclude
    |_ requiredProperties
        |_ requiredPropery (key) -- 定義過的
            |_ defaultValue

我們先來講講 <requiredProperties>,這個就是我們自定義變量的關鍵,我們自定義的所有變量都要在這裏面聲明。每個變量就是一個 <requiredProperties>,key 就是變量的名稱,defaultValue 就是變量的默認值,使用上面的 jdbc.properties 爲例。

<requiredProperties>
    <requiredProperty key="database">
        <defaultValue>demo</defaultValue>
    </requiredProperty>
    <requiredProperty key="username">
        <defaultValue>root</defaultValue>
    </requiredProperty>
    <requiredProperty key="password">
        <defaultValue>root</defaultValue>
    </requiredProperty>
</requiredProperties>
# 模板中的數據
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/${database}?characterEncoding=utf-8
jdbc.username=${username}
jdbc.password=${password}

# 使用模板創建項目後
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/demo?characterEncoding=utf-8
jdbc.username=root
jdbc.password=root

接下來我們來看看 <fileSets> 這個標記,簡單來說就是用來過濾文件的,模板在初始化時會將 <fileSets> 中定義的文件複製到要生成的項目中,同時將變量設爲我們需要的值。如果我們的 <fileSets> 爲空,那麼當我們初始化項目的時候將會變成只含有一個 pom.xml 的項目。
在這裏插入圖片描述
 一般 <fileSets> 配置需要包括以下結構

src
|_ main
    |_ java
    |_ resources
    |_ webapp
|_ test
    |_ java
    |_ resources

 相應的配置如下:

<fileSets>
    <fileSet>
        <directory>src/main/java</directory>
        <includes>
            <include>**/*.java</include>
        </includes>
    </fileSet>
    <!-- 其他目錄配置同上,省略 -->
</fileSets>

 上面是一個最基本的寫法,但是這樣只是將簡單地模板複製項目中而已,我們之前在 <requiredProperties> 中定義的變量將不會起作用,我們需要使用它的一個屬性 filtered,當這個屬性爲 true 時,我們設置的變量纔會被捕捉到,並注入我們需要的數據。

<fileSet filtered=“true”>

 恩,講到這裏其實已經差不多了,現在就剩最後一個問題了,也就是我們最開始提到過的 包與代碼的結構 這個問題,這個問題相比較其他的屬性設置問題已經算簡單得不得了了可以通過 <fileSet>packaged 屬性來建立。

模板應用到項目的模板
java
 |_ controller
 |_ service
 |_ dao
 |_ domain
 |_ Main.java
java
 |_ com
   |_ tree
     |_ controller
     |_ service
     |_ dao
     |_ domain
     |_ Main.java

以這張表爲例,要達到圖二的效果我們只需要這麼配置,如下

<fileSet packaged=“true”>

最後變成這個樣子

<fileSets>
    <fileSet filtered="true" packaged="true">
        <directory>src/main/java</directory>
        <includes>
            <include>**/*.java</include>
        </includes>
    </fileSet>
</fileSets>

總結

步驟
  1. 通過上面講的建立一個模板
  2. 在模板項目目錄下打開終端輸入 mvn install
  3. 在終端使用 mvn archetype:crawl 生成 archetype-catalog.xml
    或 mvn archetype:update-local-catalog 更新本地模板索引
使用
  1. 在終端中輸入 mvn archetype:generate -DarchetypeCatalog=local
  2. 在 eclipse 創建 Maven 項目那裏點擊添加本地目錄文件,就是步驟 8 說的 archetype-catalog.xml(默認位於 .m2 目錄下)
  3. 在 IDEA 創建 Maven 項目那個頁面點擊添加,然後輸入模板的座標(groupId,artifactId,version)

這裏有一個現成的 Maven Archetype 可供參考:簡單的 SSM 集成


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章