本文能夠幫助你加深對Maven的總體認識,不是一篇基礎文章。若是你如今尚未用 Maven 跑過 HelloWorld,那麼本文可能不適合你。html
Maven 官網: https://maven.apache.org
Maven 3.3.9版本文檔: http://maven.apache.org/ref/3...
Maven是一個項目管理工具,它包含了一個項目對象模型 (Project Object Model),一組標準集合,一個項目生命週期(Project Lifecycle),一個依賴管理系統(Dependency Management System),和用來運行定義在生命週期階段(phase)中插件(plugin)目標(goal)的邏輯。java
maven把項目的構建劃分爲不一樣的生命週期(lifecycle)。粗略一點的話,它這個過程(phase)包括:mysql
maven中全部的執行動做(goal)都須要指明本身在這個過程當中的執行位置,而後maven執行的時候,就依照過程的發展依次調用這些goal進行各類處理。linux
這個也是maven的一個基本調度機制。通常來講,位置稍後的過程都會依賴於以前的過程。固然,maven一樣提供了配置文件,能夠依照用戶要求,跳過某些階段。web
maven使用以下幾個要素來惟必定位某一個輸出物: groupId:artifactId:packaging:version 。好比org.springframework:spring:2.5 。每一個部分的解釋以下:算法
version 一個項目的特定版本。發佈的項目有一個固定的版本標識來指向該項目的某一個特定的版本。而正在開發中的項目能夠用一個特殊的標識,這種標識給版本加上一個"SNAPSHOT"的標記。spring
<major version>.<minor version>.<incremental version>-<qualifier>
,好比1.2.3-beta-01。要說明的是,maven本身判斷版本的算法是major,minor,incremental部分用數字比較,qualifier部分用字符串比較,因此要當心 alpha-2和alpha-15的比較關係,最好用 alpha-02的格式。maven在版本管理時候可使用幾個特殊的字符串 SNAPSHOT ,LATEST ,RELEASE 。好比"1.0-SNAPSHOT"。各個部分的含義和處理邏輯以下說明:sql
項目結構圖:數據庫
parent ├─childA(model層) │ └─pom.xml(jar) ├─childB(web層) │ └─pom.xml(war) └─pom.xml(pom)
parent中執行mvn install
就能將 childA和childB 一塊兒編譯apache
parent的pom.xml作以下配置:
<groupId>com.song</groupId> <artifactId>parent</artifactId> <version>1.0-SNAPSHOT</version> <packaging>pom</packaging> <!-- pom表示它是一個被繼承的模塊 --> <modules> <module>childA</module> <!-- 不加module則不會被聯合編譯 --> <module>childB</module> </modules>
childA和childB的pom.xml都須要配置parent,防止引入的包衝突(若是不加parent,會分別去編譯他們引入的依賴,會重複引入包):
<!-- childA 的 pom.xml--> <parent> <artifactId>parent</artifactId> <groupId>com.song</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>childA</artifactId> <packaging>jar</packaging> <!-- childB 的 pom.xml--> <parent> <artifactId>parent</artifactId> <groupId>com.song</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>childB</artifactId> <packaging>war</packaging>
<dependency> <groupId>com.module</groupId> <artifactId>childA</artifactId> <!--加上childA的依賴--> <version>1.0-SNAPSHOT</version> </dependency>
parent中加上<dependencyManagement>
,child項目就能夠繼承parent項目的依賴,而且在child中能夠不用加version了。
<dependencyManagement> <dependencies> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>2.5</version> </dependency> </dependencies> </dependencyManagement>
若是不顯示執行 <scope> 屬性時,默認 <scope>compile</scope>
。
scope 屬性包括:
<dependency>
在全部的classpath中可用,同時它們也會被打包詳細可參考: https://maven.apache.org/guid...
maven的依賴關係是有傳遞性的。如:A-->B,B-->C。但有時候,項目A可能不是必需依賴C,所以須要在項目A中排除對A的依賴。在maven的依賴管理中,有兩種方式能夠對依賴關係進行,分別是可選依賴(Optional Dependencies)以及依賴排除(Dependency Exclusions)。
當一個項目A依賴另外一個項目B時,項目A可能不多一部分功能用到了項目B,此時就能夠在A中配置對B的可選依賴。舉例來講,一個相似hibernate的項目,它支持對mysql、oracle等各類數據庫的支持,可是在引用這個項目時,咱們可能只用到其對mysql的支持,此時就能夠在這個項目中配置可選依賴。
配置可選依賴的緣由:一、節約磁盤、內存等空間;二、避免license許可問題;三、避免類路徑問題,等等。
<dependency> <groupId>sample.ProjectB</groupId> <artifactId>Project-B</artifactId> <version>1.0</version> <scope>compile</scope> <optional>true</optional> </dependency>
假設以上配置是項目A的配置,即:Project-A --> Project-B。在編譯項目A時,是能夠正常經過的。
若是有一個新的項目X依賴A,即:Project-X -> Project-A。此時項目X就不會依賴項目B了。若是項目X用到了涉及項目B的功能,那麼就須要在pom.xml中從新配置對項目B的依賴。
當一個項目A依賴項目B,而項目B同時依賴項目C,若是項目A中由於各類緣由不想引用項目C,在配置項目B的依賴時,能夠排除對C的依賴。
示例(假設配置的是A的pom.xml,依賴關係爲:A --> B; B --> C):
<dependency> <groupId>sample.ProjectB</groupId> <artifactId>Project-B</artifactId> <version>1.0</version> <scope>compile</scope> <exclusions> <exclusion> <groupId>sample.ProjectC</groupId> <artifactId>Project-C</artifactId> </exclusion> </exclusions> </dependency>
固然,對於多重依賴,配置也很簡單,參考以下示例:
Project-A -> Project-B -> Project-D -> Project-E <! -- This dependency should be excluded --> -> Project-F -> Project C
A對於E至關於有多重依賴,咱們在排除對E的依賴時,只須要在配置B的依賴中進行便可:
<dependency> <groupId>sample.ProjectB</groupId> <artifactId>Project-B</artifactId> <version>1.0-SNAPSHOT</version> <exclusions> <exclusion> <groupId>sample.ProjectE</groupId> <artifactId>Project-E</artifactId> </exclusion> </exclusions> </dependency>
不配置Plugin時,Maven默認會使用如下插件。若是針對各個 plugin 有特殊配置的話,須要顯示指定 plugin 和 屬性配置。
plugin | function | life cycle phase |
---|---|---|
maven-clean-plugin | 清理上一次執行建立的target文件 | clean |
maven-resources-plugin | 處理資源文件 | resources,testResources |
maven-compiler-plugin | 編譯Java代碼 | compile、testCompile |
maven-surefire-plugin | 執行單元測試文件 | test |
maven-jar-plugin | 建立 jar | package |
maven-install-plugin | 拷貝jar到本地的maven倉庫 .m2/repository 下面 | install |
maven-deploy-plugin | 發佈 jar | deploy |
maven-site-plugin | 生成文檔 | site |
maven-site-plugin:將工程全部文檔生成網站,生成的網站界面默認和apache的項目站點相似,可是其文檔用doxia格式寫的,目前不支持docbook,須要用其餘插件配合才能支持。須要指出的是,在maven 2.x系列中和maven3.x的site命令處理是不一樣的,在舊版本中,用 mvn site 命令能夠生成reporting節點中的全部報表,可是在maven3中,reporting過期了,要把這些內容做爲 maven-site-plugin的configuration的內容才行。詳細內容能夠參考 http://www.wakaleo.com/blog/2...
<build> <!-- resources 是 maven-resources-plugin 的--> <resources> <resource> <directory>src/main/java</directory> <filtering>true</filtering> <!-- filtering 用來表示資源文件中的佔位符是否須要被profiles中的屬性動態替換,true爲須要替換。 --> <includes> <include>**/*.xml</include> </includes> </resource> <resource> <directory>src/main/resources</directory> <filtering>true</filtering> <includes> <include>**/*.properties</include> <include>*.xml</include> <include>*.dic</include> <include>*.txt</include> </includes> </resource> <resource> <directory>src/main/resources</directory> <filtering>false</filtering> <includes> <include>*.p12</include> </includes> </resource> </resources> <plugins> <!-- maven-compiler-plugin編譯源代碼。 指定maven編譯的jdk版本,若是不指定,maven3默認用jdk 1.5 maven2默認用jdk1.3 windows默認使用GBK編碼,java項目常常編碼爲utf8,也須要在compiler插件中指出,不然中文亂碼可能會出現編譯錯 --> <plugin> <artifactId>maven-compiler-plugin</artifactId> <version>3.1</version> <configuration> <source>1.8</source> <target>1.8</target> <encoding>UTF-8</encoding> </configuration> </plugin> <!-- maven-resources-plugin用來處理資源文件,默認的主資源文件目錄是src/main/resources。 --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-resources-plugin</artifactId> <version>2.6</version> <configuration> <encoding>UTF-8</encoding> </configuration> </plugin> </plugins> </build>
當使用SpringBoot開發項目的時候,會使用到spring-boot-maven-plugin
插件
官方文檔: https://docs.spring.io/spring...
Spring Boot Maven plugin有5個Goals:
命令 | 說明 |
---|---|
spring-boot:repackage | 默認goal。在mvn package以後,再次打包可執行的jar/war,<br/>並將mvn package生成的軟件包重命名爲*.original |
spring-boot:run | 運行Spring Boot應用 |
spring-boot:start | 在mvn integration-test階段,進行Spring Boot應用生命週期的管理 |
spring-boot:stop | 在mvn integration-test階段,進行Spring Boot應用生命週期的管理 |
spring-boot:build-info | 生成Actuator使用的構建信息文件build-info.properties |
其中比較重要的命令是:
mvn package spring-boot:repackage
執行後會看到生成的兩個jar文件,一個是*.jar
,另外一個是*.jar.original
。
這是因爲在執行上述命令的過程當中,Maven首先在package
階段打包生成*.jar
文件;而後執行spring-boot:repackage
從新打包
咱們也能夠跳過repackage
階段:
clean deploy -D spring-boot.repackage.skip=true
加上-D spring-boot.repackage.skip=true
參數便可,此時只會生成一個普通的jar包
maven-source-plugin提供項目自動將源碼打包併發布的功能,在須要發佈源碼項目的pom.xml文件中添加以下代碼便可:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-source-plugin</artifactId> <configuration> </configuration> <executions> <execution> <id>attach-sources</id> <goals> <goal>jar</goal> </goals> </execution> </executions> </plugin>
執行 mvn install
,maven會自動將source install到repository 。
執行 mvn deploy
,maven會自動將source deploy到remote-repository 。
執行 mvn source:jar
,單獨打包源碼。
注意:在多項目構建中,將source-plugin置於頂層或parent的pom中並不會發揮做用,必須置於具體項目的pom中。
tomcat插件有兩種:tomcat-maven-plugin 和 tomcat7-maven-plugin,使用方式基本相同。
tomcat7-maven-plugin 插件使用
<plugin> <groupId>org.apache.tomcat.maven</groupId> <artifactId>tomcat7-maven-plugin</artifactId> <version>2.2</version> <configuration> <path>/</path> <port>8080</port> <uriEncoding>UTF-8</uriEncoding> <server>tomcat7</server> </configuration> <executions> <execution> <phase>package</phase> <goals> <goal>run</goal> </goals> </execution> </executions> </plugin>
命令:
tomcat7:deploy --部署一個web war包 tomcat7:reload --從新加載web war包 tomcat7:start --啓動tomcat tomcat7:stop --中止tomcat tomcat7:undeploy --中止一個war包 tomcat7:run --啓動嵌入式tomcat ,並運行當前項目
tomcat-maven-plugin 插件使用
<plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>tomcat-maven-plugin</artifactId> <version>1.1</version> <configuration> <path>/helloworld</path> <port>8080</port> <uriEncoding>UTF-8</uriEncoding> <url>http://localhost:8080/manager/html</url> <server>tomcat6</server> <systemProperties> <JAVA_OPTS>-Xms256m -Xmx512m -XX:MaxPermSize=512m</JAVA_OPTS> </systemProperties> </configuration> </plugin>
命令:
tomcat:deploy --部署一個web war包 tomcat:reload --從新加載web war包 tomcat:start --啓動tomcat tomcat:stop --中止tomcat tomcat:undeploy --中止一個war包 tomcat:run --啓動嵌入式tomcat ,並運行當前項目
配置參數:
path:是訪問應用的路徑
port:是tomcat 的端口號
uriEncoding:URL按UTF-8進行編碼,這樣就解決了中文參數亂碼。
Server:指定tomcat名稱。
自動部署包含三個步驟:
編譯打包、上傳到服務器、在服務器上執行linux命令
Maven項目可以使用 mvn install 指令打包,打包完成後包位於target目錄下,要想在遠程服務器上部署,首先要將包上傳到服務器。
首先在本地的setting.xml中配置server的信息,包括id,用戶名,密碼。(固然也能夠在pom.xml裏面配置)
<servers> <server> <id>linux_server</id> <username>user</username> <password>password</password> </server> </servers>
pom.xml
<build> <extensions> <extension> <groupId>org.apache.maven.wagon</groupId> <artifactId>wagon-ssh</artifactId> <version>2.8</version> </extension> </extensions> <plugins> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>wagon-maven-plugin</artifactId> <version>1.0</version> <configuration> <serverId>linux_server</serverId> <fromFile>target/test.war</fromFile> <url>scp://user:password@192.168.20.128/home/tomcat7/webapps</url> </configuration> </plugin> </plugins> </build>
<serverId>linux_server</serverId>
: 在setting.xml中配置的server的id名字<fromFile>target/test.war</fromFile>
:是要上傳到服務器的文件,通常來講是jar或者war包 <url>scp://user:password@192.168.20.128/home/tomcat7/webapps</url>
:配置服務器的用戶、密碼、地址以及文件上傳的目錄
命令:
# 對項目進行打包和上傳操做 mvn clean install wagon:upload-single
若是覺的wagon命令太長,能夠設置 excutions 來配置phase和goals來簡化命令。
<!-- 若是運行的命令中沒有「-D maven.deploy.skip=true」不配置distributionManagement 則會報錯:-DaltDeploymentRepository=id::layout::url parameter 由於不加maven.deploy.skip=true,則會使用maven的deploy,又使用wagon的deploy。而maven的deploy是須要配置distributionManagement的 <distributionManagement> <repository> <id>${serverid}</id> <url>scp://192.168.20.128/home/java/exe</url> </repository> </distributionManagement> --> <build> <extensions> <extension> <groupId>org.apache.maven.wagon</groupId> <artifactId>wagon-ssh</artifactId> <version>2.8</version> </extension> </extensions> <plugins> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>wagon-maven-plugin</artifactId> <version>1.0</version> <configuration> <fromFile>target/test.jar</fromFile> <url>scp://user:password@192.168.20.128/home/java/exe</url> <commands> <command>pkill -f /home/java/exe/test.jar</command> <!-- 殺死原來的進程,-f 是用來查找命令參數,禁止使用pkill java來殺死進程,也能夠是 pkill -f test.jar --> <command>nohup java -jar /home/java/exe/test.jar > /home/java/exe/$(date +%Y%m%d-%H%M%S).log & </command> <!-- 從新啓動test.jar,& 是xml的轉義字符,表示 &--> </commands> <displayCommandOutputs>true</displayCommandOutputs> <!-- 顯示運行命令的輸出結果 --> </configuration> </plugin> </plugins> </build>
命令
<!--install、wagon:upload-single、wagon:sshexec 分別對項目進行打包、上傳、運行command命令的操做--> mvn clean install wagon:upload-single wagon:sshexec
<build> <extensions> <extension> <groupId>org.apache.maven.wagon</groupId> <artifactId>wagon-ssh</artifactId> <version>2.8</version> </extension> </extensions> <plugins> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>wagon-maven-plugin</artifactId> <version>1.0</version> <configuration> <fromFile>target/javawebdeploy.war</fromFile> <url>scp://user:password@192.168.20.128/home/tomcat7/webapps</url> <commands> <!-- 重啓Tomcat --> <command>sh /home/tomcat7/bin/shutdown.sh</command> <command>rm -rf /home/tomcat7/webapps/test</command> <command>sh /home/tomcat7/bin/startup.sh</command> </commands> <displayCommandOutputs>true</displayCommandOutputs> </configuration> </plugin> </plugins> </build>
命令
mvn clean install wagon:upload-single wagon:sshexec
若是以爲 mvn clean package wagon:upload-single wagon:sshexec
命令太長了很差記,那麼能夠配置execution,在運行deploy的同時運行upload-single和sshexec。
<build> <extensions> <extension> <groupId>org.apache.maven.wagon</groupId> <artifactId>wagon-ssh</artifactId> <version>2.8</version> </extension> </extensions> <plugins> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>wagon-maven-plugin</artifactId> <version>1.0</version> <executions> <execution> <id>upload-deploy</id> <!-- 運行deploy命令時同時運行upload-single和sshexec --> <phase>deploy</phase> <goals> <goal>upload-single</goal> <goal>sshexec</goal> </goals> <configuration> <fromFile>target/test.war</fromFile> <url>scp://user:password@192.168.20.128/home/tomcat7/webapps</url> <commands> <command>sh /home/tomcat7/bin/shutdown.sh</command> <command>rm -rf /coder/tomcat7/webapps/test</command> <command>sh /coder/tomcat7/bin/startup.sh</command> </commands> <displayCommandOutputs>true</displayCommandOutputs> </configuration> </execution> </executions> </plugin> </plugins> </build>
部署命令
<!-- 便可使用mvn clean package來代替mvn clean package wagon:upload-single wagon:sshexec --> <!-- 必須加 -D maven.deploy.skip=true ,表示跳過maven自身的deploy使用wagon的deploy。不然報錯「-DaltDeploymentRepository=id::layout::url parameter」 --> mvn clean deploy -D maven.deploy.skip=true
首先在本地的setting.xml中配置server的信息,包括id,用戶名,密碼。(固然也能夠在pom.xml裏面配置)
<servers> <server> <id>linux_server</id> <username>user</username> <password>password</password> </server> </servers>
pom.xml
<build> <extensions> <extension> <groupId>org.apache.maven.wagon</groupId> <artifactId>wagon-ssh</artifactId> <version>2.8</version> </extension> </extensions> <plugins> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>wagon-maven-plugin</artifactId> <version>1.0</version> <configuration> <serverId>linux_server</serverId> <url>scp://192.168.20.128/home/tomcat7/webapps</url> <displayCommandOutputs>true</displayCommandOutputs> <!-- 顯示運行命令的輸出結果 --> </configuration> <executions> <!-- 將war包上傳到服務器並重啓服務器 --> <execution> <id>upload-war-to-server</id> <phase>deploy</phase> <goals> <goal>upload-single</goal> <goal>sshexec</goal> </goals> <configuration> <fromFile>target/test.war</fromFile> <commands> <command>datefilename=$(date +%Y%m%d-%H%M%S);cp /home/tomcat7/webapps/test.war /home/tomcat7/webapps/test.war.$datefilename</command> <!--備份舊的war包--> <command>ps -ef | grep /home/tomcat7/ | grep -v grep | awk {'print $2'} | sed -e "s/^/kill -9 /g" | sh</command> <!-- 關閉tomcat7 --> <command>rm -rf /home/tomcat7/webapps/test</command> <!-- 刪除test項目 --> <command>export JAVA_HOME=/home/jdk/jdk1.8.0_91;sh /home/tomcat7/bin/startup.sh</command> <!-- 啓動tomcat --> </commands> </configuration> </execution> </plugin> </plugins> </build>
部署命令
# 必須加 -D maven.deploy.skip=true ,表示跳過maven自身的deploy使用wagon的deploy。不然報錯「-DaltDeploymentRepository=id::layout::url parameter」 mvn clean deploy -D maven.deploy.skip=true
Maven打包時能夠對web.xml
中的spring.profiles.active
值進行替換。
先web.xml
中配置一個佔位符${profiles.active}
:
<context-param> <param-name>spring.profiles.active</param-name> <param-value>${profiles.active}</param-value> </context-param>
在pom.xml
配置maven-war-plugin
:
<!-- 打war包時替換佔位符 --> <build> <plugin> <artifactId>maven-war-plugin</artifactId> <version>3.2.2</version> <configuration> <!-- 過濾Deployment Descriptor並將文件中的佔位符替換爲pom.xml中對應的<properties>值 --> <filteringDeploymentDescriptors>true</filteringDeploymentDescriptors> </configuration> </plugin> </build> <!-- 默認的maven profile --> <properties> <profiles.active>dev</profiles.active> </properties> <profiles> <profile> <id>dev</id> <properties> <profiles.active>dev</profiles.active> </properties> </profile> <profile> <id>release</id> <properties> <profiles.active>release</profiles.active> </properties> </profile> </profiles>
以上配置完成後,再經過mvn package -Pdev
或mvn package -Preelase
打包後,${profiles.active}<
佔位符就被替換爲dev
或release
<profiles> <profile> <!-- 本地開發環境 --> <id>dev</id> <properties> <profiles.active>dev</profiles.active> </properties> <activation> <!-- 設置默認激活這個配置 --> <activeByDefault>true</activeByDefault> </activation> </profile> <profile> <!-- 發佈環境 --> <id>release</id> <properties> <profiles.active>release</profiles.active> </properties> </profile> <profile> <!-- 測試環境 --> <id>beta</id> <properties> <profiles.active>beta</profiles.active> </properties> </profile> </profiles> <build> <finalName>helloworld</finalName> <resources> <!-- 先所有不包含 --> <resource> <directory>src/main/resources</directory> <excludes> <exclude>config/</exclude> </excludes> </resource> <!-- 再指定須要包含的文件夾 --> <resource> <directory>src/main/resources/config/${profiles.active}</directory> <targetPath>.</targetPath> </resource> </resources> </build>
id表明這個環境的惟一標識,在 mvn install -Pdev 來指定。
此properties定義了三個環境,分別是dev(開發環境)、beta(測試環境)、release(發佈環境)
activeByDefault=true表明若是不指定某個固定id的profile,那麼就使用這個環境
使用 mvn install -Pdev
會將 id 爲 dev 的 profile 中的<properties>
定義的屬性profiles.active
自動替換${profiles.active}
佔位符的變量。最終build到classpath的資源文件由maven-resources-plugin來指定,爲src/main/resources/config/dev文件下的全部文件。
若是想要整合Maven profile和Spring Framework profile,Maven打包時能夠對web.xml
中的spring.profiles.active
值進行替換。
先web.xml
中配置一個佔位符${profiles.active}
:
<context-param> <param-name>spring.profiles.active</param-name> <param-value>${profiles.active}</param-value> </context-param>
在pom.xml
配置maven-war-plugin
:
<!-- 打war包時替換佔位符 --> <build> <plugin> <artifactId>maven-war-plugin</artifactId> <version>3.2.2</version> <configuration> <!-- 過濾Deployment Descriptor並將文件中的佔位符替換爲pom.xml中對應的<properties>值 --> <filteringDeploymentDescriptors>true</filteringDeploymentDescriptors> </configuration> </plugin> </build> <!-- 默認的maven profile --> <properties> <profiles.active>dev</profiles.active> </properties> <profiles> <profile> <id>dev</id> <properties> <profiles.active>dev</profiles.active> </properties> </profile> <profile> <id>release</id> <properties> <profiles.active>release</profiles.active> </properties> </profile> </profiles>
以上配置完成後,再經過mvn package -Pdev
或mvn package -Preelase
打包後,${profiles.active}<
佔位符就被替換爲dev
或release
全部pom中的元素均可以用 project. 前綴進行引用,如下是部分經常使用的
全部用的的 settings.xml 中的設定均可以經過 settings. 前綴進行引用
系統的環境變量經過 env. 前綴引用
全部JVM中定義的java系統屬性.
<project> ... <properties> <project.build.finalName>hellowolrld</project.build.finalName> </properties> ... </project>
則引用 ${project.build.finalName} 就會獲得值 hellowolrld
parent工程的pom.xml中的變量用前綴 ${project.parent}
引用. 上級工程的版本也能夠這樣引用: ${parent.version }
.
參考文章:
https://blog.csdn.net/wwbmyos...
https://blog.csdn.net/j080624...
http://xxgblog.com/2015/10/23...
https://blog.csdn.net/java_an...
https://blog.csdn.net/xiao__g...