天天看點

多子產品(module)maven工程archetype模闆建立1.建立參照工程2.建立工程模闆3 釋出模闆

最近公司要搭建一套新的平台,期間要建立多個工程,每建立一個工程都需要耗費大量的時間,包括各子子產品的添加、jar的依賴等等,因為同一公司,同一項目代碼風格基本一緻,那麼建立一個模闆工程,自動生成代碼,根據業務需要隻需要将生成的代碼稍微修改甚至不修改直接就編寫業務代碼的計劃就提上日程了。而且使用模闆生成代碼還有一個好處就是代碼風格一緻。說幹就幹。

1.建立參照工程

既然是建立模闆工程,那麼首先生成的工程代碼是什麼樣的,就要有一個參照,是以我們首先建立一個參照工程,就是我們最終要在項目中用到的工程結構是什麼樣的,此步驟是為了确定我們要建立的模闆生成的代碼都要有哪些子產品,要有哪些常用的配置,要有哪些常用依賴等等。我是使用 interj idea來開發的,是以在IDE中建立一個多module的maven工程,過程不在贅述,結構如下圖,(如果對項目工程比較熟悉或已經有現有的工程可以參考,那麼可以忽略此步驟,直接進行步驟2)

多子產品(module)maven工程archetype模闆建立1.建立參照工程2.建立工程模闆3 釋出模闆

展開看下細節

多子產品(module)maven工程archetype模闆建立1.建立參照工程2.建立工程模闆3 釋出模闆
多子產品(module)maven工程archetype模闆建立1.建立參照工程2.建立工程模闆3 釋出模闆
多子產品(module)maven工程archetype模闆建立1.建立參照工程2.建立工程模闆3 釋出模闆
多子產品(module)maven工程archetype模闆建立1.建立參照工程2.建立工程模闆3 釋出模闆

2.建立工程模闆

有了參考之後,我們就要将參考的工程變成模闆,以後用此模闆生成的代碼都和參考工程具有同樣的結構、配置、依賴等等。模闆也是一個maven工程,我們在IDE中建立一個工程test-archetype,建立如圖所示的目錄結構(注:必須包含用紅框标注的目錄結構且命名必須和圖中示例一樣,下面會逐個分析各目錄結構的用途)

多子產品(module)maven工程archetype模闆建立1.建立參照工程2.建立工程模闆3 釋出模闆

2.1 模闆工程pom.xml

maven模闆主要是用到了archetype插件,pom配置如下:

<?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/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.test</groupId>
    <artifactId>test-archetype</artifactId>
    <version>1.0-SNAPSHOT</version>

    <packaging>jar</packaging>
    <build>
        <pluginManagement>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-archetype-plugin</artifactId>
                    <version>2.4</version>
                </plugin>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <configuration>
                        <source>1.7</source>
                        <target>1.7</target>
                    </configuration>
                </plugin>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-resources-plugin</artifactId>
                    <configuration>
                        <encoding>UTF-8</encoding>
                    </configuration>
                </plugin>
            </plugins>
        </pluginManagement>
    </build>

</project>
           

2.2 archetype-resources目錄

此目錄是用來放置通過此模闆商城的項目要有的檔案,或者說是要生成的代碼的鏡像,也就是這個目錄裡放的是參照工程中的代碼和配置檔案,如圖所示

多子產品(module)maven工程archetype模闆建立1.建立參照工程2.建立工程模闆3 釋出模闆

但是并不是簡單的将參照工程中的目錄和檔案拷貝過來,還要對目錄和檔案做一些修改,否則使用此模闆生成的目錄名稱和代碼的包路徑都是固定的,并不會随着我們使用不同的ArtifactId而變化,下面我們說下如何修改。

對于子產品(module)名和子產品的目錄命名,我們一般使用父工程的ArtifactId加上子產品的功能來命名,例如商品系統,父工程的ArtifactId為product,其中api子產品命名就是product-api等。那麼在模闆定義中如何來動态的建立子子產品的目錄呢,這時使用__rootArtifactId__占位符來動态擷取父工程的ArtifactId,那麼此時在archetype-resources目錄下的api子產品的目錄名就不是參照工程中定義的archetype-reference-api,而是__rootArtifactId__-api了,最終archetype-resources目錄下的結構如圖

多子產品(module)maven工程archetype模闆建立1.建立參照工程2.建立工程模闆3 釋出模闆

對于代碼包路徑目錄的動态建立,在參照工程中Service子產品,的啟動類ServiceLauncher.java的目錄結構是:工程所在目錄\archetype-reference-service\src\main\java\com\test\archetype\reference\service\launcher,如圖

多子產品(module)maven工程archetype模闆建立1.建立參照工程2.建立工程模闆3 釋出模闆

其中子產品(module)目錄archetype-reference-service,通過上面說的使用占位符__rootArtifactId__我們已經可以動态生成了,那麼下面的src\main\java\com\test\archetype\reference\service\launcher目錄中尤其是com\test\archetype\reference這一段如何解決呢,總不能所有的項目中都要使用這個包路徑結構吧,如果仔細看過代碼我們能發現,在參照工程中所有代碼的包路徑結構都是已com\test\archetype\reference開始的,如果我們建立一個商品系統的代碼,也應該是所有的代碼結構都是已com\test\product開始,我們成這樣的基礎包結構為BasePackage,所有的子子產品的包路徑結構都應該是基礎包路徑加上子產品包路徑,錄入商品系統api子產品的包路徑為com\test\product\api\xxx\xxx.......,那麼在模闆工程中,我們隻建立基礎包結構之後的目錄結構,在參照工程中的ServiceLauncher的目錄結構在子產品工程中就變成了如圖所示

多子產品(module)maven工程archetype模闆建立1.建立參照工程2.建立工程模闆3 釋出模闆

說完了子產品目錄和包目錄的動态,那麼代碼檔案中的包名怎麼動态呢,例如java檔案中的import引用,spring配置檔案中的類路徑使用,sh腳步檔案中的類路徑使用等等,這些檔案中使用的能動态配置嗎,答案是可以。要使用變量。

對于代碼中import或者spring、xml中引用類路徑的,我們都使用自定義變量來替換,例如使用變量package,在代碼中,在配置檔案中,如下圖所示

多子產品(module)maven工程archetype模闆建立1.建立參照工程2.建立工程模闆3 釋出模闆
多子產品(module)maven工程archetype模闆建立1.建立參照工程2.建立工程模闆3 釋出模闆
多子產品(module)maven工程archetype模闆建立1.建立參照工程2.建立工程模闆3 釋出模闆

其他類型的替換一樣,都是使用變量,例如pom檔案中的資訊,都是要動态生成的,一樣使用變量

多子產品(module)maven工程archetype模闆建立1.建立參照工程2.建立工程模闆3 釋出模闆

當然,這其中有些變量是系統支援的,有些變量是自定義的,例如rootArtifactId、project.version等都是系統支援的,有些是自動以的,例如上面用到的package,自定義的變量在使用模闆的生成代碼的時候要提供并複制,這個後面會細說。好了,到現在為止archetype-resources目錄的作用以及該目錄下的目錄和檔案如果動态定義以及說完了,那麼現在可以生成模闆了嗎,當然還不行,要需要一個中繼資料檔案,就是下面要降到的META-INF/maven目錄下的archetype-metadata.xml檔案了

2.3 archetype-metadata.xml

有了模闆的鏡像檔案,這時候還要告訴怎麼使用這些檔案,這時就需要模闆的中繼資料檔案了,中繼資料檔案定義如下:

<?xml version="1.0" encoding="UTF-8"?>
<archetype-descriptor name="my-archetype">
	<requiredProperties>
		<requiredProperty key="groupId">
			<defaultValue>com.test</defaultValue>
		</requiredProperty>
		<requiredProperty key="artifactId">
			<defaultValue>test.archetype</defaultValue>
		</requiredProperty>
		<requiredProperty key="package">
			<defaultValue>com.test.archetype</defaultValue>
		</requiredProperty>
	</requiredProperties>
    <fileSets>
        <fileSet filtered="true" encoding="UTF-8">
            <directory></directory>
            <includes>
                <include>*.xml</include>
                <include>*.properties</include>
            </includes>
        </fileSet>
    </fileSets>
	<modules>
		<module id="${rootArtifactId}-api" dir="__rootArtifactId__-api" name="${rootArtifactId}-api">
			<fileSets>
				<fileSet filtered="true" encoding="UTF-8" packaged="true">
					<directory>src/main/java</directory>
					<includes>
						<include>**/*.java</include>
						<include>**/*.txt</include>
					</includes>
				</fileSet>
				<fileSet filtered="true" encoding="UTF-8">
					<directory></directory>
					<includes>
						<include>pom.xml</include>
					</includes>
				</fileSet>
			</fileSets>
		</module>
        <module id="${rootArtifactId}-dao" dir="__rootArtifactId__-dao" name="${rootArtifactId}-dao">
            <fileSets>
                <fileSet filtered="true" encoding="UTF-8" packaged="true">
                    <directory>src/main/java</directory>
                    <includes>
                        <include>**/*.java</include>
                        <include>**/*.txt</include>
                    </includes>
                </fileSet>
                <fileSet filtered="true" encoding="UTF-8" packaged="false">
                    <directory>src/main/resources</directory>
                    <includes>
                        <include>**/*.*</include>
                    </includes>
                </fileSet>
                <fileSet filtered="true" encoding="UTF-8">
                    <directory></directory>
                    <includes>
                        <include>pom.xml</include>
                    </includes>
                </fileSet>
            </fileSets>
        </module>
        <module id="${rootArtifactId}-domain" dir="__rootArtifactId__-domain" name="${rootArtifactId}-domain">
            <fileSets>
                <fileSet filtered="true" encoding="UTF-8" packaged="true">
                    <directory>src/main/java</directory>
                    <includes>
                        <include>**/*.java</include>
                        <include>**/*.txt</include>
                    </includes>
                </fileSet>
                <fileSet filtered="true" encoding="UTF-8">
                    <directory></directory>
                    <includes>
                        <include>pom.xml</include>
                    </includes>
                </fileSet>
            </fileSets>
        </module>
        <module id="${rootArtifactId}-service" dir="__rootArtifactId__-service" name="${rootArtifactId}-service">
            <fileSets>
                <fileSet filtered="true" encoding="UTF-8" packaged="true">
                    <directory>src/main/java</directory>
                    <includes>
                        <include>**/*.java</include>
                        <include>**/*.txt</include>
                    </includes>
                </fileSet>
                <fileSet filtered="true" encoding="UTF-8" packaged="false">
                    <directory>src/main/assemble</directory>
                    <includes>
                        <include>**/*.xml</include>
                    </includes>
                </fileSet>
                <fileSet filtered="true" encoding="UTF-8" packaged="false">
                    <directory>src/main/bin</directory>
                    <includes>
                        <include>**/*.sh</include>
                        <include>**/*.bat</include>
                    </includes>
                </fileSet>
                <fileSet filtered="true" encoding="UTF-8" packaged="false">
                    <directory>src/main/resources</directory>
                    <includes>
                        <include>**/*.*</include>
                    </includes>
                </fileSet>
                <fileSet filtered="true" encoding="UTF-8">
                    <directory></directory>
                    <includes>
                        <include>pom.xml</include>
                    </includes>
                </fileSet>
            </fileSets>
        </module>
        <module id="${rootArtifactId}-web" dir="__rootArtifactId__-web" name="${rootArtifactId}-web">
            <fileSets>
                <fileSet filtered="true" encoding="UTF-8" packaged="true">
                    <directory>src/main/java</directory>
                    <includes>
                        <include>**/*.java</include>
                        <include>**/*.txt</include>
                    </includes>
                </fileSet>
                <fileSet filtered="true" encoding="UTF-8" packaged="false">
                    <directory>src/main/webapp</directory>
                    <includes>
                        <include>**/*.*</include>
                    </includes>
                </fileSet>
                <fileSet filtered="true" encoding="UTF-8" packaged="false">
                    <directory>src/main/resources</directory>
                    <includes>
                        <include>**/*.*</include>
                    </includes>
                </fileSet>
                <fileSet filtered="true" encoding="UTF-8">
                    <directory></directory>
                    <includes>
                        <include>pom.xml</include>
                    </includes>
                </fileSet>
            </fileSets>
        </module>
	</modules>
</archetype-descriptor>
           

檔案根節點的name用來定義此模闆的名稱

根節點下的fileSets用來定義包含archetype-resources目錄下的哪些檔案,directory為空表示這些檔案要放在生成的父工程路徑下面

modules節點用來定義生成的代碼的子產品清單

module節點用來定義子產品詳細資訊,dir熟悉對應archetype-resources下的目錄,name和id屬性用來定義在生成的工程中的子產品名

着重說下fileSet标簽下的packaged和filtered熟悉

packaged屬性用來辨別,在生成代碼時用不用建立包目錄,例如上面我們的ServiceLauncher類的路徑是src/main/java/service/launcher/ServiceLauncher.java,如果我們給定了package為com.xxx.product并且此屬性是true,那麼生成代碼時會為我們建立com/xxx/product目錄結構,ServiceLauncher類的路徑就變成了src/main/java/com/xxx/product/service/launcher/ServiceLauncher.java

filtered屬性用來辨別,要不要在生成代碼時,替換掉鏡像檔案中的變量,上面我們再代碼中使用的package變量,如果給定了package為com.xxx.product并且此屬性為true,那麼檔案中所有出現${package}的地方都會變成com.xxx.product

3 釋出模闆

好了,至此,子產品已經定義好了,如果使用這個模闆呢,在子產品工程裡,我們可以執行maven的install指令将模闆裝載到本地倉庫,也可以使用maven的deploy指令,将模闆釋出到遠端倉庫,怎麼通過deploy指令釋出到遠端倉庫網上教程很多,就不說了。釋出完隻後如何用模闆呢。

使用IDE建立工程時,已intelliJ IDEA為例,在建立工程時添加模闆,填寫模闆的資訊,(模闆也是一個jar,跟普通jar依賴一樣)

多子產品(module)maven工程archetype模闆建立1.建立參照工程2.建立工程模闆3 釋出模闆
多子產品(module)maven工程archetype模闆建立1.建立參照工程2.建立工程模闆3 釋出模闆

添加隻後在模闆清單中就能看到你定義的模闆了,選擇模闆,下一步,填寫新項目的groupId、artifactId等資訊

多子產品(module)maven工程archetype模闆建立1.建立參照工程2.建立工程模闆3 釋出模闆

繼續下一步

多子產品(module)maven工程archetype模闆建立1.建立參照工程2.建立工程模闆3 釋出模闆

不知道還有同學記得我嗎上面用到了一個自定義的變量package嗎,顯然這裡的properties定義中沒有這個變量,那麼這時候就要添加你在模闆中用到的自定義變量了,添加後如圖

多子產品(module)maven工程archetype模闆建立1.建立參照工程2.建立工程模闆3 釋出模闆

好了,一直下一步,知道工程建立完成。

除了使用IDE添加模闆之外,還可以使用腳步通過mvn的archetype:generate指令來實作代碼建立,下面是我寫的bat腳本,供大家參考,使用此腳本之前本地mvn環境要搭建好。

@echo off
echo 開始運作代碼生成腳本,運作此腳本前請堅持本地maven是否已經配置
echo 請輸入groupId:
set/p GROUP_ID=
echo 請輸入artifactId:
set/p ARTIFACT_ID=
echo 請輸入package:
set/p BASE_PACKAGE=


call mvn archetype:generate -DgroupId=%GROUP_ID% -DartifactId=%ARTIFACT_ID% -Dpackage=%BASE_PACKAGE% -Dversion="1.0.0" -DarchetypeGroupId=com.test -DarchetypeArtifactId=test-archetype -DarchetypeVersion=1.0.0-SNAPSHOT 

pause