Maven详解及实例
1 什么是Maven
? ?Maven對項目進行模型抽象,充分運用的面向對象的思想,Maven可以通過一小段描述信息來管理項目的構建,報告和文檔的軟件項目管理工具。Maven 除了以程序構建能力為特色之外,還提供高級項目管理工具。簡單的來說Maven是一個項目管理工具,它包含了一個項目對象模型(POM:Project Object Model),一組標準集合,一個項目生命周期(Project Lifecycle),一個依賴管理系統(Dependency Management System),用來運行在生命周期階段中插件目標的邏輯。
2 為什么要使用maven
??使用maven主要有2點:依賴管理和生命周期
??(1)依賴管理:對第三方的jar包進行統一的管理
??①添加第三方jar包:開發時使用第三方jar包最簡單的方法就是復制粘貼到WEB-INF目錄下的lib目錄下,每個新工程都要復制粘貼,從而造成工作區中存在大量重復的文件。通過maven只需要維護一個文本形式的jar包的引用,稱之為“坐標”,自動從maven倉庫中下載到工程(體現了代碼重用的原則)
??②jar包之間的依賴關系:jar包往往不是孤立存在的,很多jar包都需要在其他jar包的支持下才能夠正常工作,Maven就可以替我們自動的將當前jar包所依賴的其他所有jar包全部導入進來,無需人工參與不必了解這個依賴關系。
??③jar包之間的沖突:前面是jar包少了無法工作,有時jar包多了項目仍然無法正常工作,Maven中內置了兩條依賴原則:最短路徑者優先和先聲明者優先
??(2)生命周期
??生命周期的一鍵構建,提供了一套對項目生命周期管理的標準,開發人員,測試人員統一使用maven進行項目的構建.項目的生命周期管理:編譯,測試,打包,部署,運行
?
3 Maven的核心概念
??核心概念包括以下幾個方面:POM,約定的目錄結構,坐標,依賴,倉庫,生命周期,插件和目標,繼承,聚合
3.1 POM
??Project Object Model:項目對象模型。將Java工程的相關信息封裝為對象作為便于操作和管理的模型。Maven工程的核心配置,配置Maven就是pom.xml文件中的配置。
3.2 約定的目錄結構
??JavaEE開發領域普遍認同一個觀點:約定>配置>編碼。意思就是能用配置解決的問題就不編碼,能基于約定的就不進行配置。而Maven正是因為指定了特定文件保存的目錄才能夠對我們的Java工程進行自動化構建。 目錄結構含義參見前面的描述。
3.3 坐標
??Maven的坐標使用三個向量在Maven的倉庫中唯一的確定一個Maven工程: ??①groupId:公司或組織的域名倒序+當前項目名稱 ??②artifactId:當前項目的模塊名稱 ??③version:當前模塊的版本
? <groupId>com.quinto</groupId><artifactId>rtwd-parent</artifactId><version>1.0-SNAPSHOT</version>??將上面3個向量連起來:com.quinto.rtwd-parent的字符串作為目錄結構到倉庫中查找:com/quinto/rtwd-parent/1.0-SNAPSHOT/rtwd-parent-1.0-SNAPSHOT.jar ??注意:自己的Maven工程必須執行安裝操作才會進入倉庫。安裝的命令是:mvn install
3.4 依賴
??依賴:當A jar包需要用到B jar包中的類時,我們就說A對B有依賴。
??當前工程會到本地倉庫中根據坐標查找它所依賴的jar包,配置的基本形式是使用dependency標簽指定目標jar包的坐標。如下:
<dependencies><dependency><!--坐標--><groupId>junit</groupId><artifactId>junit</artifactId><version>${junit.version}</version><!--依賴的范圍--><scope>test</scope></dependency> </dependencies>??直接依賴和間接依賴:如果A依賴B,B依賴C,那么A→B和B→C都是直接依賴,而A→C是間接依賴。
3.4.1 依賴的范圍
??(1)compile ??①main目錄下的Java代碼可以訪問這個范圍的依賴 ??②test目錄下的Java代碼可以訪問這個范圍的依賴 ??③部署到Tomcat服務器上運行時要放在WEB-INF的lib目錄下 ??如:對主程序的依賴。主程序、測試程序和服務器運行時都需要用到。
??(2)test ??①main目錄下的Java代碼不能訪問這個范圍的依賴 ??②test目錄下的Java代碼可以訪問這個范圍的依賴 ??③部署到Tomcat服務器上運行時不會放在WEB-INF的lib目錄下 ??如:對junit的依賴。僅僅是測試程序部分需要。
??(3)provided ??①main目錄下的Java代碼可以訪問這個范圍的依賴 ??②test目錄下的Java代碼可以訪問這個范圍的依賴 ??③部署到Tomcat服務器上運行時不會放在WEB-INF的lib目錄下 ??如:servlet-api在服務器上運行時,Servlet容器會提供相關API,所以部署的時候不需要。
??(4)其他:runtime、import、system等。
??各個依賴范圍的作用可以概括為下圖:
?
3.4.2 依賴的傳遞性
??當存在間接依賴的情況時,主工程對間接依賴的jar只有依賴范圍為compile時可以訪問
3.4.3 依賴的原則
??(1)路徑最短者優先:
?
??(2)路徑相同時先聲明者(dependency標簽配置的先后順序)優先:
?
3.4.4 排除依賴
??如果直接引入的依賴A,B都有傳遞依賴于C,而且對C依賴的版本不一樣,那就有可能在運行時產生依賴沖突,可以通過排除掉一些傳遞依賴來避免沖突,如下
? ? ? <dependency><groupId>org.apache.spark</groupId><artifactId>spark-core_2.12</artifactId><version>3.0.0</version><!--依賴排除--><exclusions><!--需要排除的依賴可以寫多個--><exclusion><groupId>org.apache.hadoop</groupId><artifactId>hadoop-client</artifactId></exclusion></exclusions></dependency>3.4.5 統一管理jar包版本
??通過properties標簽可以聲明自定義屬性,在pom中別的地方就可以用${屬性名}引用屬性的值,如下
? <properties><!-- junit --><junit.version>4.12</junit.version><!-- logger --><log4j.version>2.11.0</log4j.version></properties> ? ?<dependencyManagement><dependencies><!-- junit --><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>${junit.version}</version></dependency><!-- log4j-core --><dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-core</artifactId><version>${log4j.version}</version></dependency></dependencies></dependencyManagement>3.5 倉庫
??(1)分類
??本地倉庫 : 相當于緩存。本地倉庫存儲在本地的磁盤當中,里面存放的是經常使用的jar包。
??遠程倉庫 :
??①私服:架設在當前局域網環境下,基本每個公司都會有自己的私服,當本地的磁盤中不存在需要的jar包資源,則會請求私服進行資源下載。
??②中央倉庫 : 遠程倉庫,架設在Interne上,由jar專業團隊統一維護。
??③中央倉庫的鏡像:架設在各個大洲,為中央倉庫分擔流量。減輕中央倉庫的壓力,同時更快的響應用戶請求。
??在pom.xml中配置倉庫的位置
? <repositories><repository><id>ali-repo</id><name>ali-repo</name><url>http://maven.aliyun.com/nexus/content/groups/public/</url></repository><repository><id>mvn-repo</id><name>mvn-repo</name><url>https://mvnrepository.com</url><layout>default</layout></repository></repositories>??(2)倉庫中的文件 ??①Maven的插件 ??②我們自己開發的項目的模塊 ??③第三方框架或工具的jar包
3.6 生命周期
??(1)Maven生命周期 ??Maven生命周期定義了各個構建環節的執行順序,有了這個清單,Maven就可以自動化的執行構 建命令了。 ??Maven有三套相互獨立的生命周期,分別是: ①Clean Lifecycle在進行真正的構建之前進行一些清理工作。②Default Lifecycle構建的核心部分,編譯,測試,打包,安裝,部署等等。③Site Lifecycle生成項目報告,站點,發布站點。 它們是相互獨立的,可以僅僅調用clean來清理工作目錄,僅僅調用site來生成站點。當然你也可以直接運行 mvn clean install site 運行所有這三套生命周期。
??每套生命周期都由一組階段(Phase)組成,我們平時在命令行輸入的命令總會對應于一個特定的階段。比如,運行mvn clean,這個clean是Clean生命周期的一個階段。有Clean生命周期,也有clean階段。
??(2)clean生命周期 ??Clean生命周期一共包含了三個階段:①pre-clean 執行一些需要在clean之前完成的工作 ②clean 移除所有上一次構建生成的文件 ③post-clean 執行一些需要在clean之后立刻完成的工作
??(3)Site生命周期 ??①pre-site 執行一些需要在生成站點文檔之前完成的工作②site 生成項目的站點文檔③post-site 執行一些需要在生成站點文檔之后完成的工作,并且為部署做準備④site-deploy 將生成的站點文檔部署到特定的服務器上 這里經常用到的是site階段和site-deploy階段,用以生成和發布Maven站點,這可是Maven相當強大的功能,Manager比較喜歡,文檔及統計數據自動生成,很好看。
??(4)Default生命周期 ??Default生命周期是Maven生命周期中最重要的一個,絕大部分工作都發生在這個生命周期中。這里,只解釋一些比較重要和常用的階段:
validate generate-sources process-sources generate-resources process-resources 復制并處理資源文件,至目標目錄,準備打包。 compile 編譯項目的源代碼。 process-classes generate-test-sources process-test-sources generate-test-resources process-test-resources 復制并處理資源文件,至目標測試目錄。 test-compile 編譯測試源代碼。 process-test-classes test 使用合適的單元測試框架運行測試。這些測試代碼不會被打包或部署。 prepare-package package 接受編譯好的代碼,打包成可發布的格式,如JAR。 pre-integration-test integration-test post-integration-test verify install將包安裝至本地倉庫,以讓其它項目依賴。 deploy將最終的包復制到遠程的倉庫,以讓其它開發人員與項目共享或部署到服務器上運行。??(5)生命周期與自動化構建 ??運行任何一個階段的時候,它前面的所有階段都會被運行,如運行mvn install 的時候,代碼會被編譯,測試,打包。這就是Maven為什么能夠自動執行構建過程的各個環節的原因。此外,Maven的插件機制是完全依賴Maven的生命周期的,因此理解生命周期至關重要。
3.7 插件和目標
??(1)Maven的核心僅僅定義了抽象的生命周期,具體的任務都是交由插件完成的。 ??(2)每個插件都能實現多個功能,每個功能就是一個插件目標。 ??(3)Maven的生命周期與插件目標相互綁定,以完成某個具體的構建任務。 ??如:compile就是插件maven-compiler-plugin的一個功能;pre-clean是插件maven-clean-plugin的一個目標。
<plugins><plugin><!-- 編譯說明 --><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.2</version><configuration> <!--作為DOM對象的配置--> ?<source>1.7</source><target>1.7</target></configuration></plugin></plugins> 這里就是告訴我們的代碼使用的是什么jdk版本。<plugin>復制文件<groupId>org.apache.maven.plugins</groupId><artifactId>maven-resources-plugin</artifactId><executions><execution><phase>compile</phase> 綁定了目標的構建生命周期階段,如果省略,目標會被綁定到源數據里配置的默認階段 ?<goals> 配置的執行目標 ?<goal>copy-resources</goal></goals><configuration> <outputDirectory>${project.build.outputDirectory}</outputDirectory><resources><resource><directory>src/main/resources/{dev}</directory></resource></resources><overwrite>true</overwrite></configuration></execution></executions></plugin> 這是拷貝配置信息的一段xml,由于我們有三個環境,所以為了便捷可以直接使用插件,進行拷貝一些配置信息。 <plugin>打包聲明<groupId>org.apache.maven.plugins</groupId><artifactId>maven-war-plugin</artifactId><version>2.6</version><configuration><warName>3hfund</warName><failOnMissingWebXml>false</failOnMissingWebXml><webResources><resource><directory>${basedir}/src/main/webapp</directory><filtering>true</filtering><includes><include>WEB-INF/web.xml</include></includes></resource></webResources></configuration> </plugin> 使用了maven-war-plugin插件進行打包。 <profile> 可以通過 -P ID 來激活<id>PUB</id> ID 標識符<properties><env>pub</env> properties 定義 key-value, 這里 key 是 env, value 是 PROD</properties><activation><activeByDefault>true</activeByDefault> </activation> </profle> 定義了打包過程中使用的配置文件,打包使用 mvn package –P PUB則打包配置文件是pub的war包。3.8 繼承
??使用繼承機制就可以將這樣的依賴信息統一提取到父工程模塊中進行統一管理。
3.8.1 父子工程
??創建父工程,父工程只需要保留pom.xml文件即可
? <groupId>com.quinto</groupId><artifactId>rtwd-parent</artifactId><!--父工程的打包方式為pom--><packaging>pom</packaging><version>1.0-SNAPSHOT</version>??父工程中的pom會包含module的定義,如下
? <modules><module>rtwd-common</module><module>rtwd-canal</module><module>rtwd-etl</module><module>rtwd-simulator</module></modules>??子工程中會有父工程的定義
? <parent><artifactId>rtwd-parent</artifactId><groupId>com.quinto</groupId><version>1.0-SNAPSHOT</version></parent>3.8.2 依賴繼承
??父工程引入的依賴,所有子工程都會自動繼承
3.8.3 依賴管理
??父工程通過dependencyManager聲明依賴的相關屬性(版本),但是并不會真正引入依賴。子工程在引入dependencyManager聲明的依賴時,不需要指定版本,直接繼承dependencyManager中聲明的版本
??父工程中聲明如下
? <dependencyManagement><dependencies><!-- junit --><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>${junit.version}</version></dependency></dependencyManagement>子工程中引入依賴不需要指定版本和范圍
? <dependencies><dependency><groupId>junit</groupId><artifactId>junit</artifactId></dependency></dependencies>3.9 聚合
??將多個工程拆分為模塊后,需要手動逐個安裝到倉庫后依賴才能夠生效。修改源碼后也需要逐個手動進行clean操作。而使用了聚合之后就可以批量進行Maven工程的安裝、清理工作。
??配置:在總的聚合工程中使用modules/module標簽組合,指定模塊工程的相對路徑即可。Maven可以根據各個模塊的繼承和依賴關系自動選擇安裝的順序
? <modules><module>rtwd-common</module><module>rtwd-canal</module><module>rtwd-etl</module><module>rtwd-simulator</module></modules>4 Maven安裝
??(1)檢測java環境
??Maven是使用Java開發的,所以必須知道當前系統環境中JDK的安裝目錄。
>echo %JAVA_HOME% D:\soft\jdk1.8??(2)解壓Maven的核心程序
??將maven的安裝包解壓到非中文無空格目錄下
??(3)配置環境變量
??將解壓后的路徑配置到系統環境變量中
?
?
??(4)查看是否安裝正確
>mvn -v Apache Maven 3.6.3 (cecedd343002696d0abb50b32b541b8a6ba2883f) Maven home: E:\working\maven\apache-maven-3.6.3\bin\.. Java version: 1.8.0_181, vendor: Oracle Corporation, runtime: D:\soft\jdk1.8\jre Default locale: zh_CN, platform encoding: GBK OS name: "windows 10", version: "10.0", arch: "amd64", family: "windows"??(5)Maven的核心配置
??Maven的核心配置文件位置:Maven安裝目錄的conf目錄下的settings.xml
??Maven核心程序查找插件順序:本地倉庫-->遠程中央倉庫下載(不能上網則無法執行Maven的具體功能)
??Maven默認的本地倉庫:當前用戶的家目錄.m2\repository目錄
??修改settings.xml設置本地倉庫位置及配置阿里云鏡像
<localRepository>E:\working\maven\maven-repository</localRepository><mirrors><mirror><id>nexus-aliyun</id><mirrorOf>central</mirrorOf><name>Nexus aliyun</name><url>http://maven.aliyun.com/nexus/content/groups/public/</url></mirror></mirrors>5 Maven常用的命令(生命周期)
mvn clean命令; 清除target目錄 mvn compile命令; 編譯,生成target目錄 mvn test命令; 將測試代碼和核心代碼一起編譯 mvn package命令; 編譯測試代碼和核心代碼并且打包對應的包類型 mvn install命令; 編譯測試代碼和核心代碼并且打包對應的包類型并且將生成的包安裝到本地倉庫 mvn deploy命令; 用于發布項目6 pom.xml配置實例
??父工程
<?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.quinto</groupId><artifactId>rtwd-parent</artifactId><packaging>pom</packaging><version>1.0-SNAPSHOT</version><modules><module>rtwd-common</module></modules><repositories><repository><id>ali-repo</id><name>ali-repo</name><url>http://maven.aliyun.com/nexus/content/groups/public/</url></repository></repositories><properties><!-- project compiler --><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><maven.compiler.encoding>UTF-8</maven.compiler.encoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><maven.build.timestamp.format>yyyyMMddHHmmss</maven.build.timestamp.format><!-- sdk --><java.version>1.8</java.version><scala.version>2.11</scala.version><!-- junit --><junit.version>4.12</junit.version><!-- logger --><log4j.version>2.11.0</log4j.version><slf4j.version>1.7.25</slf4j.version><!-- bigdata --><hadoop.version>2.6.0</hadoop.version><hbase.version>1.2.0</hbase.version><protobuf.version>3.4.0</protobuf.version><flink.version>1.10.0</flink.version><kafka.client.version>1.0.0</kafka.client.version><kafka.version>0.11.0.2</kafka.version><canal.version>1.0.24</canal.version><!-- json --><fastjson.version>1.2.44</fastjson.version> ?</properties> ?<dependencyManagement><dependencies><!-- junit --><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>${junit.version}</version><scope>test</scope></dependency><!-- log4j-core --><dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-core</artifactId><version>${log4j.version}</version></dependency><!-- log4j-api --><dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-api</artifactId><version>${log4j.version}</version></dependency><!-- log4j-web --><dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-web</artifactId><version>${log4j.version}</version></dependency><!-- slf4j-api --><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-api</artifactId><version>${slf4j.version}</version></dependency><!-- jcl-over-slf4j --><dependency><groupId>org.slf4j</groupId><artifactId>jcl-over-slf4j</artifactId><version>${slf4j.version}</version><scope>runtime</scope></dependency><!-- log4j-slf4j-impl --><dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-slf4j-impl</artifactId><version>${log4j.version}</version></dependency><!-- hadoop --><dependency><groupId>org.apache.hadoop</groupId><artifactId>hadoop-common</artifactId><version>${hadoop.version}-${cdh.version}</version></dependency><dependency><groupId>org.apache.hadoop</groupId><artifactId>hadoop-hdfs</artifactId><version>${hadoop.version}-${cdh.version}</version></dependency><dependency><groupId>org.apache.hadoop</groupId><artifactId>hadoop-client</artifactId><version>${hadoop.version}</version></dependency><!--hbase-shaded , 用來更改hbase中的一些報名,解決protobuf的沖突問題--><dependency><groupId>org.apache.hbase</groupId><artifactId>hbase-shaded-client</artifactId><version>1.2.1</version></dependency> ?<dependency><groupId>org.apache.hbase</groupId><artifactId>hbase-shaded-server</artifactId><version>1.2.1</version></dependency><dependency><groupId>org.apache.htrace</groupId><artifactId>htrace-core</artifactId><version>3.1.0-incubating</version></dependency><!-- flink --><dependency><groupId>org.apache.flink</groupId><artifactId>flink-core</artifactId><version>${flink.version}</version></dependency><dependency><groupId>org.apache.flink</groupId><artifactId>flink-scala_${scala.version}</artifactId><version>${flink.version}</version></dependency><dependency><groupId>org.apache.flink</groupId><artifactId>flink-runtime_${scala.version}</artifactId><version>${flink.version}</version></dependency><dependency><groupId>org.apache.flink</groupId><artifactId>flink-connector-kafka-0.11_${scala.version}</artifactId><version>${flink.version}</version></dependency><dependency><groupId>org.apache.flink</groupId><artifactId>flink-table-planner_${scala.version}</artifactId><version>${flink.version}</version></dependency><dependency><groupId>org.apache.flink</groupId><artifactId>flink-streaming-scala_${scala.version}</artifactId><version>${flink.version}</version></dependency><dependency><groupId>org.apache.flink</groupId><artifactId>flink-streaming-java_${scala.version}</artifactId><version>${flink.version}</version></dependency><dependency><groupId>org.apache.flink</groupId><artifactId>flink-hbase_${scala.version}</artifactId><version>${flink.version}</version></dependency><dependency><groupId>org.apache.bahir</groupId><artifactId>flink-connector-redis_${scala.version}</artifactId><version>1.0</version></dependency><dependency><groupId>org.apache.flink</groupId><artifactId>flink-statebackend-rocksdb_${scala.version}</artifactId><version>${flink.version}</version></dependency><dependency><groupId>org.apache.flink</groupId><artifactId>flink-cep_${scala.version}</artifactId><version>${flink.version}</version></dependency><!-- kafka --><dependency><groupId>org.apache.kafka</groupId><artifactId>kafka_2.11</artifactId><version>${kafka.version}</version></dependency><dependency><groupId>org.apache.kafka</groupId><artifactId>kafka-clients</artifactId><version>${kafka.client.version}</version></dependency><!-- canal --><dependency><groupId>com.alibaba.otter</groupId><artifactId>canal.common</artifactId><version>${canal.version}</version></dependency><dependency><groupId>com.alibaba.otter</groupId><artifactId>canal.client</artifactId><version>${canal.version}</version></dependency><!-- fastjson --><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>${fastjson.version}</version></dependency></dependencies></dependencyManagement> ?<build><finalName>${project.name}</finalName><plugins><!-- 指定maven編譯的jdk版本,如果不指定,maven3默認用jdk 1.5 maven2默認用jdk1.3 --><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>${maven-compiler-plugin.version}</version><!--代碼使用的jdk版本--><configuration><!-- 字符集編碼 --><encoding>UTF-8</encoding><!-- 源代碼使用的JDK版本 --><source>1.8</source><!-- 需要生成的目標class文件的編譯版本 --><target>1.8</target><verbose>true</verbose><!-- 要使compilerVersion標簽生效,還需要將fork設為true,用于明確表示編譯版本配置的可用 --><fork>true</fork></configuration></plugin></plugins></build> </project>??子模塊
<?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"><parent><artifactId>rtwd-parent</artifactId><groupId>com.quinto</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion> ?<artifactId>rtwd-common</artifactId><dependencies><dependency><groupId>com.alibaba.otter</groupId><artifactId>canal.client</artifactId></dependency><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId></dependency><dependency><groupId>com.google.protobuf</groupId><artifactId>protobuf-java</artifactId></dependency><dependency><groupId>org.apache.kafka</groupId><artifactId>kafka-clients</artifactId></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId></dependency></dependencies> ?<build><extensions><extension><groupId>kr.motd.maven</groupId><artifactId>os-maven-plugin</artifactId><version>1.4.1.Final</version></extension></extensions><plugins><!-- Protobuf插件 --><plugin><groupId>org.xolstice.maven.plugins</groupId><artifactId>protobuf-maven-plugin</artifactId><version>0.6.1</version><configuration><protoSourceRoot>${project.basedir}/src/main/proto</protoSourceRoot><protocArtifact>com.google.protobuf:protoc:3.1.0:exe:${os.detected.classifier}</protocArtifact></configuration><executions><execution><goals><goal>compile</goal></goals></execution></executions></plugin></plugins></build> ? </project> 創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的Maven详解及实例的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 目前流行的装修风格_现在最流行的八大装修
- 下一篇: Spark内核架构