1、插件
插件通过与生命周期绑定发挥作用,插件与生命周期的绑定实际是 插件的目标 与 生命周期的阶段 的绑定
1.1、产生源码
1 <build> 2 <plugins> 3 <plugin> 4 <groupId>org.apache.maven.plugins</groupId> 5 <artifactId>maven-source-plugin</artifactId> 6 <version>2.1.2</version> 7 <executions> 8 <execution> 9 <id>attach-sources</id> 10 <goals> 11 <goal>jar</goal> 12 </goals> 13 </execution> 14 </executions> 15 </plugin> 16 </plugins> 17 </build>
1.2、产生文档
1 <plugin> 2 <groupId>org.apache.maven.plugins</groupId> 3 <artifactId>maven-javadoc-plugin</artifactId> 4 <version>2.8</version> 5 <executions> 6 <execution> 7 <id>attach-javadocs</id> 8 <goals> 9 <goal>jar</goal> 10 </goals> 11 </execution> 12 </executions> 13 </plugin>
1.3、产生可执行jar
详见:http://www.cnblogs.com/z-sm/p/5515199.html
方法:使用assembly插件,生成的jar包名为xxx-jar-with-dependencies
- 指定mainClass会把主类写到MANIFEST.MF文件里
- 指定jar-with-dependencies会把依赖考到jar包里
代码如下:
1 <plugin> 2 <groupId>org.apache.maven.plugins</groupId> 3 <artifactId>maven-assembly-plugin</artifactId> 4 <version>2.2.2</version> 5 <configuration> 6 <appendAssemblyId>false</appendAssemblyId><!--为false时把依赖包打到原始包中,为true时打到名为xxx-with-dependencies.jar包,默认为true--> 7 <archive> 8 <manifest> 9 <addClasspath>true</addClasspath> 10 <mainClass>net.sf.jsi.examples.NearestN</mainClass> 11 </manifest> 12 </archive> 13 <descriptorRefs> 14 <descriptorRef>jar-with-dependencies</descriptorRef> 15 </descriptorRefs> 16 </configuration> 17 <executions> 18 <execution> 19 <id>make-assembly</id> 20 <phase>package</phase> 21 <goals> 22 <goal>single</goal> 23 </goals> 24 </execution> 25 </executions> 26 </plugin>
1.4、编译时把依赖包整理到指定目录下
1 <plugin> 2 <groupId>org.apache.maven.plugins</groupId> 3 <artifactId>maven-dependency-plugin</artifactId> 4 <version>2.4</version> 5 <executions> 6 <execution> 7 <id>copy-dependencies</id> 8 <phase>package</phase> 9 <goals> 10 <goal>copy-dependencies</goal> 11 </goals> 12 <configuration> 13 <outputDirectory>${project.build.directory}/dependencies</outputDirectory> 14 <includeScope>compile</includeScope> 15 </configuration> 16 </execution> 17 18 <execution> 19 <id>copy-test-dependencies</id> 20 <phase>package</phase> 21 <goals> 22 <goal>copy-dependencies</goal> 23 </goals> 24 <configuration> 25 <outputDirectory>${project.build.directory}/test-dependencies</outputDirectory> 26 <excludeScope>compile</excludeScope> 27 </configuration> 28 </execution> 29 </executions> 30 </plugin>
1.5、检查定义的约定
1 <!-- Allow versions that are greater or equal to 3.0.0, and less than 2 4.0.0 --> 3 <plugin> 4 <groupId>org.apache.maven.plugins</groupId> 5 <artifactId>maven-enforcer-plugin</artifactId> 6 <version>1.1.1</version> 7 <executions> 8 <execution> 9 <id>enforce-versions</id> 10 <goals> 11 <goal>enforce</goal> 12 </goals> 13 <configuration> 14 <rules> 15 <requireMavenVersion> 16 <version>[3.0.0,4.0.0)</version> 17 </requireMavenVersion> 18 </rules> 19 </configuration> 20 </execution> 21 </executions> 22 </plugin>
1.6、设置所用JDK
Maven项目默认用1.5版本JDK,编译亦是,在Eclipse里手动改成其他版本会生效,但是maven-update project或者导到其他机器上后又会变成默认的1.5。可采用如下方法设置:
全局设置(使得默认为指定版本):在所用到的的setting.xml(不一定是maven/conf/下的setting.xml,有可能自己指定了settings.xml)的profiles元素下添加如下profile元素
1 <profile> 2 <id>jdk17</id> 3 <activation> 4 <activeByDefault>true</activeByDefault> 5 <jdk>1.7</jdk> 6 </activation> 7 <properties> 8 <maven.compiler.source>1.7</maven.compiler.source> 9 <maven.compiler.target>1.7</maven.compiler.target> 10 <maven.compiler.compilerVersion>1.7</maven.compiler.compilerVersion> 11 </properties> 12 </profile>
局部设置(针对当前项目设置):在项目的pom,xml文件中添加如下build元素
1 <build> 2 <plugins> 3 <plugin> 4 <groupId>org.apache.maven.plugins</groupId> 5 <artifactId>maven-compiler-plugin</artifactId> 6 <version>2.3.2</version> 7 <configuration> 8 <source>1.7</source> 9 <target>1.7</target> 10 <encoding>UTF-8</encoding> 11 </configuration> 12 </plugin> 13 </plugins> 14 </build>
1.7、添加资源文件pom和文件中的变量互相引用
1 <resources> 2 <resource> 3 <directory>src/main/resources</directory> 4 <filtering>true</filtering> <!--set true to enable to use pom's variables in the file or use the file's 5 k-v in this pom --> 6 <includes><!--only included files will be copied to target/classes/ ,all 7 will be copied if it is empty --> 8 <!-- <include>**/*.properties</include> <include>default_devicesn.txt</include> --> 9 </includes> 10 </resource> 11 </resources>
2、依赖
2.1、添加不在repository中的依赖
法1:(不太可行)
先下载jar包并放在项目下,然后作为dependency通过system scope加入pom。缺点:本地可运行,但使用jar-with-dependencies打包时该包将不会被包含。
1 <!--添加本地依赖--> 2 <dependency> 3 <groupId>org.apache.kafka</groupId> 4 <artifactId>kafka_2.8.0</artifactId> 5 <version>0.8.1.1</version> 6 <scope>system</scope> 7 <systemPath>${project.basedir}/lib/kafka_2.8.0-0.8.1.1.jar</systemPath> 8 </dependency> 9 10 <!--即使借助如下的resources将本地包打入目标jar,也只是作为资源加入而不是作为依赖,所以还是找不到--> 11 <!-- 12 <build> 13 <resources> 14 <resource> 15 <targetPath>lib/</targetPath> 16 <directory>lib/</directory> 17 <includes> 18 <include>**/kafka_2.8.0-0.8.1.1.jar</include> 19 </includes> 20 </resource> 21 </resources> 22 </build> 23 -->
法2:(推荐)
既然maven可以把repository中的依赖打到最后的jar包中,那么把这个外部的jar包放到repository中,也就可以让maven把这个外部的jar包打到最后的jar包中。
因此:先将库安装到本地repository: mvn install:install-file -Dfile=my-jar.jar -DgroupId=org.richard -DartifactId=my-jar -Dversion=1.0 -Dpackaging=jar ,再按通常添加dependency的方法添加该依赖。缺点:项目在其他机子开发时需要同时安装该包到目的机器repository。
也可以通过配置pom来将外部jar安装到本地repository:
1 <plugin><!-- 将本地依赖包安装到本地仓库中,使得本地依赖包也可以打到本项目的包中,从而在其他机器上也能跑 --> 2 <groupId>org.apache.maven.plugins</groupId> 3 <artifactId>maven-install-plugin</artifactId> 4 <executions> 5 <execution> 6 <id>install-external</id> 7 <phase>clean</phase><!-- 执行clean时安装 --> 8 <configuration> 9 <file>D:/eclipse/workspace/mylib/PHTree-0.0.1-SNAPSHOT.jar</file> 10 <repositoryLayout>default</repositoryLayout> 11 <groupId>zsmlib.local</groupId> 12 <artifactId>PHTree</artifactId> 13 <version>0.0.1-SNAPSHOT</version> 14 <packaging>jar</packaging> 15 <generatePom>true</generatePom> 16 </configuration> 17 <goals> 18 <goal>install-file</goal> 19 </goals> 20 </execution> 21 </executions> 22 </plugin>
2.2、多个parent
Maven pom.xml中只允许有一个parent,当需要多个parent时,可以以添加依赖的方式添加多余的parent。示例:
<dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>1.5.9.RELEASE</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
dependencies和dependencyManagement的区别:
- dependencies即使在子项目中不写该依赖项,子项目仍然会从父项目中继承该依赖项(全部继承)
- dependencyManagement里只是声明依赖,并不实现引入,因此子项目需要显示的声明需要用的依赖。如果不在子项目中声明依赖,是不会从父项目中继承下来的;只有在子项目中写了该依赖项,并且没有指定具体版本,才会从父项目中继承该项,并且version和scope都读取自父pom;另外如果子项目中指定了版本号,那么会使用子项目中指定的jar版本。故dependencyManagement通常用于统一管理项目的版本号,以确保应用的各个项目的依赖和版本一致、保证测试的和发布的是相同的成果
2.2、排除依赖与设置依赖不可传递
假设当前项目为A,引用了依赖B,而B引用了C。默认情况下A引入B后C会也被引入到A中了,可以通过exclusion排除C,这样C就不会被引入到A中。A的依赖配置示例:
//pom.xml of A <dependency><!-- B --> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <exclusions> <exclusion><!-- C --> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> </exclusion> </exclusions> </dependency>
这是引用者主动排除被引用者的子模块的情形,另一种是被引用者主动设置使得子模块对引用者不可见的。可以通过optional设置子模块不传递依赖到父模块。B中的配置实例:
//pom.xml of B <dependency><!-- C --> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <optional>true</optional> </dependency>
上面两种配置都可以C不被引入A。
3、打包与部署
package、install、deploy区别:
package命令完成了项目编译、单元测试、打包功能,但没有把打好的可执行jar包(war包或其它形式的包)布署到本地maven仓库和远程maven私服仓库
install命令完成了项目编译、单元测试、打包功能,同时把打好的可执行jar包(war包或其它形式的包)布署到本地maven仓库,但没有布署到远程maven私服仓库
deploy命令完成了项目编译、单元测试、打包功能,同时把打好的可执行jar包(war包或其它形式的包)布署到本地maven仓库和远程maven私服仓库