Maven實戰讀書筆記(15)

關於靈活的構建css

一個優秀的構建系統必須足夠靈活,它應該可以讓項目在不一樣的環境下都能成功地構建。java

例如,典型的項目都會有開發環境、測試環境和產品環境,這些環境的數據庫配置不盡相同,那麼項目構建的時候就須要可以識別所在的環境並使用正確的配置mysql

還有一種常見的狀況是,項目開發了大量的集成測試,這些測試運行起來很是耗時,不適合在每次構建項目的時候都運行,所以須要一種手段能讓咱們在特定的時候才激活這些集成測試,Maven爲了支持構建的靈活性,內置了三大特性,即屬性、Profile和資源過濾web

 

Maven屬性spring

使用Maven屬性歸類依賴sql

       <properties>數據庫

              <springframework.version>2.5.6</springframework.version>apache

       </properties>app

 

       <dependencies>webapp

              <dependency>

                     <groupId>org.springframework</groupId>

                     <artifactId>spring-core</artifactId>

                     <version>${springframework.version}</version>

              </dependency>

              <dependency>

                     <groupId>org.springframework</groupId>

                     <artifactId>spring-beans</artifactId>

                     <version>${springframework.version}</version>

              </dependency>

              ...

       </dependencies>

這多是最多見的使用Maven屬性的方式,經過<properties>元素用戶能夠自定義一個或多個Maven屬性,而後再POM的其餘地方使用${屬性名稱}的方式引用該屬性,這種作法的最大意義在於消除重複

 

Maven6類屬性

1內置屬性,主要有兩個經常使用內置屬性——${basedir} 表示項目根目錄,即包含pom.xml文件的目錄;${version} 表示項目版本

2POM屬性,用戶可使用該類屬性引用POM文件中對應元素的值,例如:

${project.artifactId}就對應了<project> <artifactId>元素的值,經常使用的POM屬性包括:

n     ${project.build.sourceDirectory}:項目的主源碼目錄,默認爲src/main/java/

n     ${project.build.testSourceDirectory}:項目的測試源碼目錄,默認爲src/test/java/

n     ${project.build.directory}:項目構建輸出目錄,默認爲target/

n     ${project.outputDirectory}:項目主代碼編譯輸出目錄,默認爲target/classes/

n     ${project.testOutputDirectory}:項目測試代碼編譯輸出目錄,默認爲target/testclasses/

n     ${project.groupId}:項目的groupId

n     ${project.artifactId}:項目的artifactId

n     ${project.version}:項目的version,與${version}等價

n     ${project.build.finalName}:項目打包輸出文件的名稱,默認爲${project.artifactId}-

     ${project.version}

這些屬性都對應了一個POM元素,它們中一些屬性的默認值都是在超級POM中定義的

3自定義屬性,用戶能夠在POM<properties>元素下自定義Maven屬性

       <project>

       ...

              <properties>

                     <my.prop>hello</my.prop>

              </properties>

       ...

       </project>

       而後在POM中其餘地方使用${my.prop}的時候會被替換成hello

4Settings屬性,與POM屬性同理,用戶使用以settings.開頭的屬性引用settings.xml文件中xml元素的值,如經常使用的${settings.localRepository}指向用戶本地倉庫的地址

5Java系統屬性,全部Java系統屬性均可以使用Maven屬性引用,例如${user.home}指向了用戶目錄,用戶可使用mvn help:system查看全部的Java系統屬性

6環境變量屬性,全部環境變量均可以使用以env.開頭的Maven屬性引用。例如${env.JAVA_HOME}指代了JAVA_HOME環境變量的值。用戶可使用mvn help:system查看全部的環境變量

 

使用POM屬性配置依賴

<dependencies>

       <dependency>

              <groupId>${project.groupId}</groupId>

              <artifactId>account-email</artifactId>

              <version>${project.version}</version>

       </dependency>

       <dependency>

              <groupId>${project.groupId}</groupId>

              <artifactId>account-persist</artifactId>

              <version>${project.version}</version>

       </dependency>

</dependencies>

 

使用Maven屬性配置插件

修改測試報告目錄

<plugin>

       <groupId>org.apache.maven.plugins</groupId>

       <artifactId>maven-surefire-plugin</artifactId>

       <version>2.5</version>

       <configuration>

              <reportsDirectory>

                     ${project.build.directory}/test-reports

              </reportsDirectory>

       </configuration>

</plugin>

 

構建環境的差別,考慮一下這種狀況

在不一樣的環境中,項目的源碼應該使用不一樣的方式進行構建,最多見的就是數據庫配置了

例如在開發的過程當中,有些項目會在src/main/resources/目錄下放置帶有以下內容的數據庫配置文件:

database.jdbc.driverClass=com.mysql.jdbc.Driver

database.jdbc.connectionURL=jdbc:mysql://localhost:3306/test

database.jdbc.username=dev

database.jdbc.password=dev-pwd

這本沒什麼問題,可當測試人員想要構建項目產品並進行測試的時候,他們每每須要使用不一樣的數據庫,這時的數據庫配置文件多是這樣的:

database.jdbc.driverClass=com.mysql.jdbc.Driver

database.jdbc.connectionURL=jdbc:mysql://10.1.0.56:3306/test

database.jdbc.username=test

database.jdbc.password=test-pwd

鏈接數據庫的URL、用戶名和密碼都發生了變化,相似地,當項目被髮布到產品環境的時候,所使用的數據庫配置又是另一套了。這個時候,比較原始的作法是,使用與開發環境同樣的構建,而後再測試或者發佈產品以前再手動更改這些配置。這是可行的,也是比較常見的,但確定不是最好的方法。本書已經不止一次強調,手動每每就意味着低效和錯誤,所以須要找到一種方法,使它可以自動對構建環境的差別

Maven的答案是針對不一樣的環境生成不一樣的構件。也就是說,在構建項目的過程當中,Maven就已經將這種差別處理好了

 

資源過濾

爲了應對環境的變化,首先須要使用Maven屬性將這些將會發生變化的部分提取出來。

將上面的配置,用Maven屬性取代

database.jdbc.driverClass=${db.driver}

database.jdbc.connectionURL=${db.url}

database.jdbc.username=${db.username}

database.jdbc.password=${db.password}

這裏定義了4Maven屬性:db.driverdb.urldb.usernamedb.password

 

使用一個額外的profile包裹自定義Maven屬性

針對開發環境的數據庫配置

<profiles>

       <profile>

              <id>dev</id>

              <properties>

                     <db.driver> com.mysql.jdbc.Driver </db.driver>

                     <db.url> jdbc:mysql://localhost:3306/test </db.url>

                     <db.username> dev </db.username>

                     <db.password> dev-pwd </db.password>

              </properties>

       </profile>

</profiles>

對上面這些配置進行解釋

Maven屬性定義與直接在POMproperties元素下定義沒什麼區別,只是使用了一個iddevprofile,其目的是將開發環境下的配置與其餘環境區分開

 

那麼,有了屬性定義,配置文件中也使用了這些屬性,一切OK了嗎?

仍是不行,Maven屬性默認只有在POM中才會被解析。也就是說,${db.username}放到POM中會變成test,可是若是放到src/main/resources目錄下的文件中,構建的時候它將仍然仍是${db.username},所以,須要讓Maven解析資源文件中的Maven屬性

資源文件的處理實際上是maven-resources-plugin作的事情,它默認的行爲只是將項目主資源文件複製到主代碼編譯輸出目錄中,將測試資源文件複製到測試代碼編譯輸出目錄中,不過只要經過一些簡單的POM配置,該插件就可以解析資源文件中的Maven屬性,即開啓資源過程

 

Maven默認的主資源目錄和測試資源目錄

默認狀況下是定義在超級POM中,要爲資源目錄開啓過濾,只要在此基礎上添加一行filtering配置便可

爲主資源目錄開啓過濾

<resources>

       <resource>

              <directory>${project.basedir}/src/main/resources</directory>
              <filtering>true</filtering>

       </resource>

</resources>

爲測試資源目錄開啓過濾

<resources>

       <resource>

              <directory>${project.basedir}/src/test/resources</directory>
              <filtering>true</filtering>

       </resource>

</resources>

 

配置多個資源目錄

<resources>

       <resource>

              <directory>src/main/resources</directory>
              <filtering>true</filtering>

       </resource>

</resources>

<resources>

       <resource>

              <directory>src/main/sql</directory>
              <filtering>false</filtering>

       </resource>

</resources>

其中src/main/resources開啓了過濾,而src/main/sql沒有啓用過濾

 

執行mvn clean install -Pdev命令

mvn-P參數表示在命令行激活一個profile,這裏激活了iddevprofile。構建完成後,輸出目錄中的數據庫配置就是開發環境的配置了

 

 

爲了構建差別的jdbc配置,咱們作了哪些配置?

1、數據庫配置的變化部分提取成了Maven屬性

2、在POMprofile中定義了這些屬性的值

3、爲資源目錄開啓了屬性過濾

4、最後須要在命令行激活profileMaven就可以在構建項目的時候使用profile中屬性值替換數據庫配置文件中的屬性引用

 

激活profileMaven支持不少種激活Profile的方式

1、命令行激活

使用mvn命令行參數-P加上profileid來激活profile,多個id之間以逗號分隔

使用命令激活dev-xdev-y兩個profile

mvn clean install -Pdev-x,dev-y

2settings文件顯式激活

若是用戶但願某個profile默認一直處於激活狀態,就能夠配置settings.xml文件的activeProfiles元素,表示其配置的profile對於全部項目都處於激活狀態

settings文件顯式激活profile

<settings>

...

       <activeProfiles>

              <activeProfile>dev-x</activeProfile>

       </activeProfiles>

...

</settings>

3、系統屬性激活

配置當某系統屬性存在的時候,自動激活profile

當系統屬性test存在時,激活此profile

<profiles>

       <profile>

              <activation>

                     <property>

                            <name>test</name>

                     </propety>

              </activation>

              ...

       </profile>

</profiles>

當系統屬性test存在,且值等於x的時候激活profile

<profiles>

       <profile>

              <activation>

                     <property>

                            <name>test</name>

                            <value>x</value>

                     </propety>

              </activation>

              ...

       </profile>

</profiles>

上面的配置,不要忘了在命令行聲明系統屬性

mvn clean install -Dtest=x

所以,這其實也是一種從命令行激活profile的方法,並且多個profile徹底可使用同一個系統屬性來激活

4、操做系統環境激活

Profile還能夠自動根據操做系統環境激活,若是構建在不一樣的操做系統有差別,用戶徹底能夠將這些差別寫進profile,而後配置它們自動基於操做系統激活

基於操做系統環境激活profile

<profiles>

       <profile>

              <activation>

                     <os>

                            <name>Windows XP</name>

                            <family>Windows</family>

                            <arch>x86</arch>

                            <version>5.1.2600</version>

                     </os>

              </activation>

              ...

       </profile>

</profiles>

這裏family的值包括WindowsUNIXMac等,而其餘幾項namearchversion,用戶能夠經過查看環境中的系統屬性os.nameos.archos.version得到

5、文件存在與否激活

Maven可以根據項目中某個文件存在與否來決定是否激活profile

基於文件存在與否激活profile

<profiles>

       <profile>

              <activation>

                     <file>

                            <missing>x.properties</missing>

                            <exists>y.properties</ exists >

                     </file>

              </activation>

              ...

       </profile>

</profiles>

6、默認激活

用戶能夠在定義profile的時候指定其默認激活

默認激活profile

<profiles>

       <profile>

              <id>dev</id>

              <activation>

                     <activeByDefault>true</activeByDefault>

              </activation>

              ...

       </profile>

</profiles>

使用activeByDefault元素用戶能夠指定profile自動激活,不過須要注意的是,若是POM中有任何一個profile經過以上其餘任意一種方式被激活了,全部的默認激活配置都會失效

 

項目中有不少profile,用戶怎麼知道哪一個激活了?

maven-help-plugin提供一個目標幫助用戶瞭解當前激活的profile

mvn help:active-profiles

maven-help-plugin還有另一個目標用來列出當前全部的profile

mvn help:all-profiles

 

那麼,profile的種類有哪些?或者說在哪裏能夠配置profile

1pom.xml,很顯然,pom.xml中聲明的profile值對當前項目有效

2、用戶settings.xml:用戶目錄下.m2/settings.xml中的profile對本機上該用戶全部的Maven項目有效

3、全局settings.xmlMaven安裝目錄下conf/settings.xml中的profile對本機上全部的Maven項目有效

4profiles.xmlMaven 2):還能夠在項目根目錄下使用一個額外的profiles.xml文件來聲明profile,不過該特性已經在Maven 3中被移除。建議用戶將這類profile移到settings.xml

 

POM中的profile可以使用的元素

由於profile能夠伴隨pom.xml一塊兒存在,因此可使用不少POM元素

<project>

       <repositories></repositories>

       <pluginRepositories></pluginRepositories>

       <distributationManagement></distributationManagement>

       <dependencyManagement></dependencyManagement>

       <modules></modules>

       <properties></properties>

       <reporting></reporting>

       <build>

              <plugins></plugins>

              <defaultGoal></defaultGoal>

              <resources></resources>

              <testResources></testResources>

              <finalName></finalName>

       </build>

</project>

 

POM外部的profile可以使用的元素

因爲沒法保證外部的profile隨着特定的pom.xml一塊兒分發,因此外部的profile可以使用的元素不多

<project>

       <repositories></respositories>

       <pluginRepositories></pluginRepositories>

       <properties></properties>

</project>

外部的profile僅僅能影響項目的倉庫和Maven屬性

 

Web資源過濾

Web項目中,資源文件一樣位於src/main/resources目錄下,它們經處理後會位於WAR包的WEB-INF/classes目錄下,這也是Java代碼編譯打包後的目錄。也就是說,這類資源文件在打包事後位於應用程序的classpath中。

Web項目中海油另一類資源文件,默認它們的源碼位置src/main/webapp/目錄,經打包後位於WAR包的根目錄。

例如,一個Web項目的css源碼文件在src/main/webapp/css/目錄,項目打包後能夠在WAR包的css/目錄下找到對應的css文件。這一類資源文件稱做web資源文件,它們在打包事後不位於應用程序的classpath

與通常的資源文件同樣,web資源文件默認不會被過濾。開啓通常資源文件的過濾也不會影響到web資源文件

不過有的時候,咱們可能但願在構建項目的時候,爲不一樣的客戶使用不同的資源文件(例如客戶的logo圖片不一樣,或者css主題不一樣)。這時能夠在web資源文件中使用Maven屬性,例如用 ${client.logo}表示客戶的logo圖片,用${client.theme}表示客戶的css主題。而後使用profile分別定義這些Maven屬性的值

 

針對不一樣客戶web資源的profile

<profiles>

       <profile>

              <id>client-a</id>

              <properties>

                     <client.logo>a.jpg</client.logo>

                     <client.theme>red</client.theme>

              </properties>

       </profile>

       <profile>

              <id>client-b</id>

              <properties>

                     <client.logo>b.jpg</client.logo>

                     <client.theme>blue</client.theme>

              </properties>

       </profile>

</profiles>

 

web資源目錄src/main/webapp/開啓過濾

<plugin>

       <groupId>org.apache.maven.plugins</groupId>

       <artifactId>maven-war-plugin</artifactId>

       <version>2.1-beta-1</version>

       <configuration>

              <resource>

                     <filtering>true</filtering>

                     <directory>src/main/webapp</directory>

                     <includes>

                            <include>**/*.css</include>

                            <include>**/*.js</include>

                     </includes>

              </resource>

       </configuration>

</plugin>

對上述配置進行解釋

1web資源目錄src/main/webapp(這也是默認的web資源目錄)

2、配置filtering開啓過濾,而且使用includes指定要過濾的文件,這裏是全部的cssjs文件

3、激活某個profile進行構建,mvn clean install -Pclient-a,告訴web資源文件使用logo圖片a.jpg,使用css主題red

 

profile中激活集成測試?

 

什麼是集成測試?

 

如何在Maven中使用TestNG

相關文章
相關標籤/搜索