Maven知识点梳理(持续更新)

Maven一个项目的构建和管理工具

相关配置

项目级:定义在项目的POM文件pom.xml中
用户级:%USER_HOME%/.m2/settings.xml
全局:%M2_HOME%/conf/settings.xml
父POM:%M2_HOME%/lib/maven-model-builder-3.6.2.jar中的pom文件(这个文件一般不会改动)
pom.xml:

<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>
  <!--父工程的相关配置 -->
  <parent>
    <groupId>com.xxx</groupId>
    <artifactId>pdemo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
  </parent>
  <!--文档名 -->
  <artifactId>demo</artifactId>
  <!--包类型 -->
  <packaging>war</packaging>
  <!--依赖 -->
   <dependencies>
	<dependency>
		<groupId>org.springframework.security</groupId>
		<artifactId>spring-security-config</artifactId>		
	</dependency>
  </dependencies>
  <!--工程的构建过程 -->
  <build>
  	 <!--maven插件 -->
	 <plugins>
		<plugin>
			<groupId>org.apache.tomcat.maven</groupId>
			<artifactId>tomcat7-maven-plugin</artifactId>
			<configuration>
				<path>/</path>
				<port>9002</port>
			</configuration>
		</plugin>
	 </plugins>
  </build>
</project>

settings.xml:

<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">
    <!-- 本地仓库 -->	
    <localRepository>/path/to/local/repo</localRepository>
    <!-- Maven是否需要和用户交互以获得输入 -->	
    <interactiveMode>true</interactiveMode>
    <!-- 是否启动离线模式 -->	
    <offline>false</offline>
    <!-- 插件的组织ID,使用插件时在这个list里面搜索,比如什么都不配,有默认的org.apache.maven.plugins -->
    <pluginGroups>com.your.plugins</pluginGroups>
    <!-- 代理,就是代理自己去访问远程服务器,远程仓库 -->	
    <proxies>
	    <proxy>
	      <id>optional</id>
	      <active>true</active>
	      <protocol>http</protocol>
	      <username>proxyuser</username>
	      <password>proxypass</password>
	      <host>proxy.host.net</host>
	      <port>80</port>
	      <nonProxyHosts>local.net|some.host.com</nonProxyHosts>
	   </proxy>
   </proxies>
   <!-- 服务器授权信息 -->	
   <servers>
   	  <server>
	     <id>nexus-releases</id>
	     <privateKey>/path/to/private/key</privateKey>
	     <passphrase>optional; leave empty if not used.</passphrase>
	  </server>
   </servers>
   <!-- 镜像,即对repository重定向 -->	
   <mirrors>
      <mirror>
	 	  <id>mirrorId</id>
		  <!-- 镜像对应的远程仓库,需和仓库的ID匹配,使用逗号分隔多个远程仓库 -->	
		  <mirrorOf>repositoryId</mirrorOf>
		  <name>Human Readable Name for this Mirror.</name>
		  <url>http://my.repository.com/repo/path</url>
	  </mirror>
   </mirrors>
    <!-- 分发管理 。比如我需要把开发的工程打包到远程仓库里做管理-->
   <distributionManagement>    
    <repository>    
      <id>nexus-releases</id>    
      <name>Nexus Release Repository</name>    
      <url>http://127.0.0.1:8080/nexus/content/repositories/releases/</url>    
    </repository>    
    <snapshotRepository>    
      <id>nexus-snapshots</id>    
      <name>Nexus Snapshot Repository</name>    
      <url>http://127.0.0.1:8080/nexus/content/repositories/snapshots/</url>    
    </snapshotRepository>    
  </distributionManagement>
   <!-- 配置信息 -->
   <profiles>
      <profile>
	      <id>jdk-1.4</id>
	      <activation>
	        <jdk>1.4</jdk>
	      </activation>
	      <!-- 远程仓库列表 -->	
	      <repositories>
	        <repository>
	          <id>jdk14</id>
	          <name>Repository for JDK 1.4 builds</name>
	          <url>http://www.myhost.com/maven/jdk14</url>
	          <layout>default</layout>
	        </repository>
	      </repositories>
   	  </profile>
   </profiles>
</settings>

理解repository,mirror,server

  • repository
    存放各种jar包和maven插件。当向仓库请求插件或依赖的时候,会先检查local repository,如果local repository有则直接返回,否则会向remote repository请求,并缓存到local repository

  • mirror
    把请求里的remote repository地址,重定向到mirror里配置的地址。
    比如有A,B两个repository都可以找到对应资源,A为公服,B是私服。我把A作为repository,B作为mirror,实际访问的时候会到B,这样提升了下载速度。并且如果环境变化,我也可以很灵活的在repository或mirror中做切换

  • server
    访问有的repository或mirror的服务器需配置一些授权信息

profile

理解profile
  • 可以解决项目在不同环境下,用不同的配置信息做构建,或者在不同环境采用不同的构建方式来构建
  • profile在settings.xml,pom.xml里都可以做配置,如果settings.xml有profile,pom.xml里没有,则所有项目都会使用settings.xml里的profile,如果pom.xml里有,项目就会使用自己的profile。
配置profile
  • 不同环境,使用不同的配置文件构建项目
    定义profile的相关参数:

    <profiles>
        <profile>
            <!-- 本地开发环境 -->
          	<打包的时候根据该id指定:mvn package -P dev>
            <id>dev</id>
            <properties>
            	<!-- 对应了src/main/resources/dev -->
                <profiles.active>dev</profiles.active>
            </properties>
            <activation>
            	<!-- 默认激活 -->
                <activeByDefault>true</activeByDefault>
            </activation>
        </profile>
        <profile>
            <!-- 测试环境 -->
            <id>test</id>
            <properties>
            	<!-- 对应了src/main/resources/test-->
                <profiles.active>test</profiles.active>
            </properties>
        </profile>
    </profiles>
    

    根据上述参数配置资源的构建过程:

    <build>
        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <excludes>
                    <exclude>test/*</exclude>
                    <exclude>pro/*</exclude>
                    <exclude>dev/*</exclude>
                </excludes>
            </resource>
            <resource>
                <directory>src/main/resources/${profiles.active}</directory>
            </resource>
        </resources>
    </build>
    
  • 同一配置文件,通过替换占位符,被赋予不同的值
    定义profile的相关参数:

    <profiles>
    	<profile>
    	   <id>dev</id>
    	   <properties>
    		   <db.url>localhost</database.host>
    	   </properties>
    	</profile>
    	<profile>
    		<id>test</id>
    		<properties>
    			<db.url>192.168.142.154</database.host>
    		</properties>
    	</profile>
    <profiles>
    

    构建资源的配置:

    <build>
      <resources>
        <resource>
          <directory>src/main/resources</directory>
    	  <!-- 开启替换占位符 -->
          <filtering>true</filtering>
        </resource>
      </resources>
    </build>
    

    配置文件:
    src/main/resources/db.properties

    database.pool.url=${db.url}
    
  • 不同环境,用不同的构建方式做构建
    只需要把build的相关内容写到profile里面即可

Maven项目主要构建过程(build)

  1. clean(清除)
  2. default-validate(缺省验证)
  3. initialize(初始化)
  4. generate-sources, process-sources, generate-resources, process-resources(加载运行资源)
  5. compile(编译)
  6. test(执行测试用例)
  7. package(打包)
  8. verify(验证)
  9. install(安装)
  10. deploy(部署)

常用指令

  • mvn clean
    清除历史打的包(即删除target文件夹,不影响本地的maven库)

  • mvn compile
    项目编译(就是生成class文件)

  • mvn package
    项目编译打包

  • mvn xxx -Dmaven.skip.test=true
    跳过测试,对测试用例不编译也不执行

  • mvn xxx -DskipTests
    跳过测试,对测试用例不执行但会编译

  • mvn install
    项目编译打包并安装到本地maven库(解决项目间的依赖问题)

  • mvn install:install-file -DgroupId=org.freemarker -DartifactId=freemarker -Dversion=2.3.23 -Dpackaging=jar -Dfile=J:\freemarker-2.3.23.jar
    手动加入文档到maven库里(解决引入在中央仓库里没有的jar包问题)

  • mvn clean install -e -U :-e详细异常,-U强制更新

  • mvn clean package -Ptest :按profile为test的配置打包

Maven的打包规则

jar

  • 默认规则
    在这里插入图片描述
    项目路径下的target目录为maven的项目构建目录
    src/main/java 里面的*.java文件会被编译,并将生成的*.class放到target/classes目录下
    src/main/java 里面的其他文件,不会做任何操作
    src/main/resources里面的文件,会被直接拷贝到target/classes目录下
    src/test/java 里面的*.java文件会被编译,并将生成的*.class放到target/test-classes目录下
    src/test/java 里面的其他文件,不会做任何操作
    src/test/resources里面的文件,会被直接拷贝到target/test-classes目录下
    target/classes目录下的文件会被最终打到jar包里

  • 通过Maven插件,自定义打包规则

war

  • 默认规则
    在这里插入图片描述
    项目路径下的target目录为maven的项目构建目录
    src/main/java的处理规则同jar包
    src/main/resources的处理规则同jar包
    src/test/java的处理规则同jar包
    src/test/resources的处理规则同jar包
    webapp里面的的文件,会被直接拷贝到与最终打出的war包同名的一个文件夹下
    target/classes目录下的文件会被直接拷贝到与最终打出的war包同名的一个文件夹下的WEB-INF/classes目录下
    项目的相关依赖会被拷贝到与最终打出的war包同名的一个文件夹下的WEB-INF/lib目录下
    与最终打出的war包同名的文件夹下的文件会被打包成war包
  • 通过Maven插件,自定义打包规则

使用maven插件

Maven生命周期的阶段(phase)默认绑定的插件目标

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述冒号后面即是绑定的插件目标,冒号前面是插件的前缀(prefix)
关于插件的前缀(prefix),比如我们平常写的:

<!-- maven-${prefix}-plugin-->
<artifactId>maven-compiler-plugin</artifactId>
<!-- ${prefix}-maven-plugin-->
<artifactId>tomcat7-maven-plugin</artifactId>

关于插件目标(goal):为了能够复用代码,它往往能够完成多个任务, 这些功能聚集在一个插件里,每个功能就是一个目标。

配置插件所绑定的生命周期(Maven默认绑定的插件不需要配置)

<plugin>
	<groupId>org.apache.maven.plugins</groupId>
	<artifactId>maven-dependency-plugin</artifactId>
   	<executions>
       	<execution>
       	   <!--id:就是个唯一标识,随便写-->
           <id>copy</id>
           <!--phase:即绑定的生命周期-->
           <phase>install</phase>
           <goals>
           	   <!--goal:即执行的插件目标-->
               <goal>copy-dependencies</goal>
           </goals>
           <configuration>
               <outputDirectory>${project.build.directory}/lib</outputDirectory>
           </configuration>
       	</execution>
     </executions>
</plugin>

常用插件

  • tomcat7-maven-plugin:Maven内置的tomcat

  • maven-compiler-plugin:Maven编译时用的插件

  • maven-resources-plugin:Maven处理项目资源文件并拷贝到输出(构建)目录的插件

  • maven-dependency-plugin:Maven的依赖插件,负责将maven的相关依赖输出到指定目录

  • maven-jar-plugin:Maven用来打jar包的插件。可指明jar包生成位置,jar的入口类

  • maven-assembly-plugin:与maven-jar-plugin类似

  • maven-shade-plugin:Maven用来打jar的插件。可做更多详细的配置,比如:将部分jar包添加或排除,将jar包内部资源添加或排除,将依赖的类重命名并打包进来,修改包的后缀名:

  • maven-war-plugin:Maven用来打war的插件。可以配置具体哪些资源被打到什么位置等

  • maven-source-plugin:把源码也打到包里

插件使用综合实例

  • 使用Maven内置的tomcat启动服务
    相关指令: tomcat7:run ,tomcat7:exec-war , tomcat7:exec-war-only

    <plugin>
    		<groupId>org.apache.tomcat.maven</groupId>
    		<artifactId>tomcat7-maven-plugin</artifactId>
    		<version>2.2</version>
    		<configuration>
    			<!-- 指定端口 -->
    			<port>9090</port>
    			<!-- 请求路径 -->
    			<path>/</path>
    		</configuration>
    </plugin>
    
  • 指定编译的JDK版本和编码格式

    <plugin>
    		<groupId>org.apache.maven.plugins</groupId>
    		<artifactId>maven-compiler-plugin</artifactId>
    		<version>3.2</version>
    		<configuration>
    			<source>1.8</source>
    			<target>1.8</target>
    			<encoding>UTF-8</encoding>
    		</configuration>
    </plugin>
    
  • 以com.alibaba.dubbo.container.Main作为启动类打jar包

    <plugin>
    	<groupId>org.apache.maven.plugins</groupId>
    	<artifactId>maven-jar-plugin</artifactId>
    	<configuration>
    		<classesDirectory>target/classes/</classesDirectory>
    		<archive>
    			<manifest>
    				<mainClass>com.alibaba.dubbo.container.Main</mainClass>
    				<useUniqueVersions>false</useUniqueVersions>
    				<addClasspath>true</addClasspath>
    				<classpathPrefix>lib/</classpathPrefix>
    			</manifest>
    			<manifestEntries>
    				<Class-Path>.</Class-Path>
    			</manifestEntries>
    		</archive>
    	</configuration>
    </plugin>
    
  • 打jar包时,把依赖拷贝到构建目录下

    <plugin>
    	 <groupId>org.apache.maven.plugins</groupId>
    	 <artifactId>maven-dependency-plugin</artifactId>
      	 <executions>
    	     <execution>
    	         <id>copy</id>
    	         <phase>install</phase>
    	         <goals>
    	             <goal>copy-dependencies</goal>
    	         </goals>
    	         <configuration>
    	             <outputDirectory>${project.build.directory}/lib</outputDirectory>
    	         </configuration>
    	     </execution>
      	 </executions>
    </plugin>
    

报错

  • 项目启动报错
    Invalid byte 3 of 3-byte UTF-8 sequence
    在这里插入图片描述
    解决:
    maven-resources-plugin不指定的话,maven默认使用平台的编码格式
    <plugin>  
          <groupId>org.apache.maven.plugins</groupId>  
          <artifactId>maven-resources-plugin</artifactId>  
          <configuration>  
              <encoding>UTF-8</encoding>  
          </configuration>  
    </plugin>
    
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章