maven实战总结,工作中常见操作_maven的fork

本人从事网路安全工作12年,曾在2个大厂工作过,安全服务、售后服务、售前、攻防比赛、安全讲师、销售经理等职位都做过,对这个行业了解比较全面。

最近遍览了各种网络安全类的文章,内容参差不齐,其中不伐有大佬倾力教学,也有各种不良机构浑水摸鱼,在收到几条私信,发现大家对一套完整的系统的网络安全从学习路线到学习资料,甚至是工具有着不小的需求。

最后,我将这部分内容融会贯通成了一套282G的网络安全资料包,所有类目条理清晰,知识点层层递进,需要的小伙伴可以点击下方小卡片领取哦!下面就开始进入正题,如何从一个萌新一步一步进入网络安全行业。

需要体系化学习资料的朋友,可以加我V获取:vip204888 (备注网络安全)

学习路线图

其中最为瞩目也是最为基础的就是网络安全学习路线图,这里我给大家分享一份打磨了3个月,已经更新到4.0版本的网络安全学习路线图。

相比起繁琐的文字,还是生动的视频教程更加适合零基础的同学们学习,这里也是整理了一份与上述学习路线一一对应的网络安全视频教程。

网络安全工具箱

当然,当你入门之后,仅仅是视频教程已经不能满足你的需求了,你肯定需要学习各种工具的使用以及大量的实战项目,这里也分享一份我自己整理的网络安全入门工具以及使用教程和实战。

项目实战

最后就是项目实战,这里带来的是SRC资料&HW资料,毕竟实战是检验真理的唯一标准嘛~

面试题

归根结底,我们的最终目的都是为了就业,所以这份结合了多位朋友的亲身经验打磨的面试题合集你绝对不能错过!

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化资料的朋友,可以点击这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

只在 dependencyManagement 标签中生效,导入已经定义好的 pom 文件中 dependencyManagement 节点内容

<dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-framework-bom</artifactId>
      <version>4.3.16.RELEASE</version>
      <type>pom</type>
      <scope>import</scope>
    </dependency>
  </dependencies>
</dependencyManagement>

依赖机制与特性

依赖传递

  • A->B(compile):第一直接依赖
  • B->C(compile):第二直接依赖
  • A->C(compile):传递性依赖

当在A中配置

<dependency>  
    <groupId>com.B</groupId>  
    <artifactId>B</artifactId>  
    <version>1.0</version>  
</dependency>

则会自动导入 C 包。

传递性依赖的范围如下图所示:

图片

依赖调解

当传递性依赖出现问题时,能够清楚地知道该传递性依赖是从哪条依赖路径中引入的。

一、路径最近者优先原则

  • A->B->C->X(1.0)
  • A->D->X(2.0)

由于只能导入一个版本的包,按照最短路径选择导入 X(2.0)

二、第一声明者优先原则

  • A->B->Y(1.0)
  • A->C->Y(2.0)

此时由于依赖路径长度一致,按照第一声明者优先原则。在路径长度一致的前提下,如果 B 依赖在 POM 文件中声明顺序在 C 依赖之前,那么 Y(1.0) 则会被引入。如下依赖可用于测试:

<dependencies>
  <dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
    <version>4.4.1</version>
    <exclusions>
      <exclusion>
        <groupId>commons-codec</groupId>
        <artifactId>commons-codec</artifactId>
      </exclusion>
    </exclusions>
  </dependency>

  <dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi</artifactId>
    <version>3.9</version>
    <exclusions>
      <exclusion>
        <groupId>commons-codec</groupId>
        <artifactId>commons-codec</artifactId>
      </exclusion>
    </exclusions>
  </dependency>

  <dependency>
    <groupId>commons-codec</groupId>
    <artifactId>commons-codec</artifactId>
    <version>1.10</version>
  </dependency>

</dependencies>

这里有一点需要特别注意,看如下依赖:

<dependencies>
  <dependency>
    <groupId>commons-codec</groupId>
    <artifactId>commons-codec</artifactId>
    <version>1.11</version>
  </dependency>

  <dependency>
    <groupId>commons-codec</groupId>
    <artifactId>commons-codec</artifactId>
    <version>1.10</version>
  </dependency>
</dependencies>

按照两原则,期望得到的结果应该是 1.11 版本的构建将被依赖。但实际结果却依赖了 1.10 版本。what!这不是违反了 maven 依赖调解的最先定义原则?

其实这个是 dependency 插件的功能,默认采用的是复写的策略,当构建声明处于同一 pom 中,且 groupid 和 artifactId 一致时,以最新声明为准,后面的覆盖前面的。

注意这里没涉及到依赖调解的功能。我的理解是依赖调解只发生于构建来自不同 pom 时,而此时构建声明处于同一 pom,故不会触发依赖调解。

可选依赖

A->B、B->X(可选)、B->Y(可选)。

项目 A 依赖于项目 B,项目 B 依赖于项目 X 和 Y。

理论上项目 A 中,会把 B、X、Y 项目都依赖进来。

但是 X、Y 两个依赖对于 B 来讲可能是互斥的,如 B 是数据库隔离包,支持多种数据库 MySQL、Oracle,在构建 B 项目时,需要这两种数据库的支持,但在使用这个工具包时,只会依赖一个数据库。

此时就需要在 B 项目 pom 文件中将 X、Y 声明为可选依赖,如下:

<dependency>  
    <groupId>com.X</groupId>  
    <artifactId>X</artifactId>  
    <version>1.0</version>  
    <optionnal>true</optionnal>
</dependency>

<dependency>  
    <groupId>com.Y</groupId>  
    <artifactId>Y</artifactId>  
    <version>1.0</version>  
    <optionnal>true</optionnal>
</dependency>

使用 optionnal 元素标识以后,只会对当前项目 B 产生影响,当其他的项目依赖 B 项目时,这两个依赖都不会被传递。

项目 A 依赖于项目 B,如果实际应用数据库是 X, 则在 A 的 pom 中就需要显式地声明 X 依赖。

仓库

仓库分类:包括本地仓库和远程仓库。其中远程仓库包括:私服和中央仓库。搜索构建的顺序:

  • 本地仓库
  • maven settings profile 中的 repository;
  • pom.xml 中 profile 中定义的repository;
  • pom.xml 中 repositorys (按定义顺序找);
  • maven settings mirror;
  • central 中央仓库;

生命周期

Maven 的生命周期是为了对所有构建过程进行的抽象和统一,其中包含项目的清理初始化编译测试打包集成测试验证部署站点生成等几乎所有的构建步骤。

Maven 的生命周期是抽象的,本身是不做任何实际的工作。实际的任务都交给插件来完成。

意味着 Maven 只在父类中定义了算法的整体结构,子类通过重写父类的方法,来控制实际行为(设计模式中的模板方法 Template Method)。伪代码如下:

public abstract class AbstractBuilder {
    public void build() {
        init();
        compile();
        test();
        package();
        integrationTest();
        deploy();
    }
    
    protected abstract void init();
    protected abstract void compile();
    protected abstract void test();
    protected abstract void package();
    protected abstract void integrationTest();
    protected abstract void deploy();
}

三套生命周期

Maven 的生命周期并不是一个整体,Maven 拥有三套相互独立的生命周期,它们分别为 clean、default 和 site。

  • clean 生命周期的目的是清理项目;
  • default 生命周期的目的是构建项目;
  • site 生命周期的目的是建立项目站点;
单个生命周期执行顺序

每个生命周期包含一些阶段(phase),这些阶段是有顺序的,并且后面的阶段依赖于前面的阶段。

以 clean 生命周期为例,它包含的阶段有 pre-clean、clean和post-clean。当调用 pre-clean 时,只有 pre-clean 阶段得以执行;

当调用 clean 的时候,pre-clean和clean阶段会得以顺序执行,以此类推。

各个生命周期之间的关系

三套生命周期本身是相互独立的,用户可以仅调用 clean 生命周期的某个阶段,或者仅仅调用 default 生命周期的某个阶段,而不会对其他生命周期产生任何影响。

例如,当用户调用 clean 生命周期的 clean 阶段的时候,不会触发 default 生命周期的任何阶段,反之亦然。

生命周期各个阶段详解

clean

生命周期阶段描述
pre-clean执行一些清理前需要完成的工作。
clean清理上一次构建生成的文件。
post-clean执行一些清理后需要完成的工作。

default

包含 23 个阶段,此处只介绍重点步骤,如下表:

生命周期阶段描述
validate检查工程配置是否正确,完成构建过程的所有必要信息是否能够获取到。
initialize初始化构建状态,例如设置属性。
generate-sources
process-sources处理项目资源文件,处理项目主资源文件。一般来说,是对src/main/resources目录的内容进行变量替换等工作后,复制到项目输出的主classpath目录中。
generate-resources
process-resources
compile编译项目的主源码。一般来说,是编译src/main/java目录下的Java文件至项目输出的主classpath目录中。
process-classes处理编译生成的文件,例如 Java Class 字节码的加强和优化。
generate-test-sources
process-test-sources处理项目测试资源文件。一般来说,是对src/test/resources目录的内容进行变量替换等工作后,复制到项目输出的测试classpath目录中。
test-compile编译项目的测试代码。一般来说,是编译src/test/java目录下的Java文件至项目输出的测试classpath目录中。
process-test-classes
test使用适当的单元测试框架(例如JUnit)运行测试。
prepare-package在真正打包之前,为准备打包执行任何必要的操作。
package获取编译后的代码,并按照可发布的格式进行打包,例如 JAR、WAR 或者 EAR 文件。
pre-integration-test在集成测试执行之前,执行所需的操作。例如,设置所需的环境变量。
integration-test处理和部署必须的工程包到集成测试能够运行的环境中。
post-integration-test在集成测试被执行后执行必要的操作。例如,清理环境。
verify运行检查操作来验证工程包是有效的,并满足质量要求。
install安装工程包到本地仓库中,该仓库可以作为本地其他工程的依赖。
deploy拷贝最终的工程包到远程仓库中,以共享给其他开发人员和工程。

site

生命周期阶段描述
pre-site执行一些在生成项目站点之前需要完成的工作。
site生成项目站点文档。
post-site执行一些在生成项目站点之后需要完成的工作。
site-deploy将生成的项目站点发布到服务器上。

插件

Maven 三套生命周期定义各个阶段不做任何实际工作,实际工作都是由插件来完成的,每个生命周期阶段都是由插件的目标来完成。在 pom 文件中声明如下(打包源码文件插件):

<build>
  <plugins>
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-source-plugin</artifactId>
      <version>2.1.1</version>
      <executions>
        <execution>
          <id>attach-sources</id>
          <phase>verify</phase>
          <goals>
              <goal>jar-no-fork</goal>
          </goals>
        </execution>
      </executions>
    </plugin>
  </plugins>
</build>

插件目标

一个插件有可能有多个功能、每个功能就是一个目标。比如 maven-dependency-plugin 有十多个目标,每个目标对应了一个功能。

插件的目标为 dependency:analyze、dependency:tree和dependency:list。

通用写法:冒号前面是插件前缀,冒号后面是插件的目标。比如 compiler:compile。

图片

插件绑定

内置绑定

为实现快速构建,Maven 有一套内置的插件绑定。三套生命周期的插件绑定具体如下(其实是各个生命周期阶段与插件的目标的绑定)。

其中 default 生命周期的构建方式会其打包类型有关、打包类型在POM中 packaging 指定。一般有 jar、war 两种类型。下面是默认绑定插件与生命周期关系图:

图片

自定义绑定

自定义绑定允许我们自己掌控插件目标与生命周期的结合。以生成项目主代码的源码 jar 为例。

使用到的插件和它的目标为:maven-source-plugin:jar-no-fork。将其绑定到 default 生命周期阶段 verify 上(可以任意指定三套生命周期的任意阶段)。

<build>
  <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-source-plugin</artifactId>
        <version>2.1.1</version>
        <executions>
          <execution>
            <id>attach-sources</id> 
            <!-- 指定作用在生命周期的哪个阶段 -->
            <phase>verify</phase> 
            <goals>
               <!-- 指定执行绑定插件的哪些目标 -->
                <goal>jar-no-fork</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
  </plugins>
</build>

插件配置
  • 使用命令行配置

在 maven 命令中加入 -D 参数,并伴随一个参数键=参数值的形式,来配置插件目标参数。

如:maven-surefire-plugin 插件提供一个 maven.test.skip 参数,当值为 true 时会跳过执行测试:

 -- 对比 mvn install
mvn install –Dmaven.test.skip=true

  • 使用 pom 全局配置

在声明插件的时候,对插件进行一个全局配置,后面所有使用该插件的都要遵循这个配置。比如指定 maven-compile-plugin 编译 1.7 版本的源文件:

<plugin>
   <groupId>org.apache.maven.plugins</groupId>
   <artifactId>maven-compiler-plugin</artifactId>
   <configuration>
       <fork>true</fork>
       <source>1.7</source>
       <target>1.7</target>
   </configuration>
</plugin>

聚合与继承

聚合:为了一次构建多个项目模块,就需要对多个项目模块进行聚合

<modules>
    <module>模块一</module>
    <module>模块二</module>
    <module>模块三</module>
</modules>

继承:为了消除重复,把很多相同的配置提取出来,例如:dependency、grouptId,version 等

<parent>  
    <groupId>com.xxxx.maven</groupId>
    <artifactId>parent-project</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <relativePath>../ParentProject/pom.xml</relativePath>  
</parent>

以下的元素是可以被继承的:

  • groupId,项目组ID;
  • version,项目版本;
  • description,项目描述信息;
  • organazation,项目的组织信息;
  • inceptionYear,项目的创始年份;
  • developers,项目开发者信息;
  • contributors,项目的贡献者信息;
  • distributionManagement,项目的部署信息;
  • issueManagement,项目的缺陷跟踪系统信息;
  • ciManagement,项目的持续集成系统信息;
  • scm,项目的版本控制系统信息;
  • mailingLists,项目的邮件列表信息;
  • properties,自定义的Maven属性;
  • dependencies,项目的依赖配置;
  • dependencyManagement,项目的依赖管理配置;
  • repositories,项目的仓库配置;
  • build,包括项目的源码目录配置、输出目录配置、插件配置、插件管理配置等;
  • reporting,包括项目的报告输出目录配置、报告插件配置。

注意下面的元素,这些都是不能被继承的:

  • artifactId
  • name
  • prerequisites
聚合与继承之间的关系
  • 两者共同点为,打方式必须都是 pom
  • 在实际的项目中,一个 pom 既是聚合 pom 又是父 pom

:父 pom 中使用 dependencies 引入的依赖也会被子 pom 继承,所以不要将过多的实际依赖放在父 pom,父 pom 只用于管理,使用 dependencyManagement 标签。

灵活构建

使用属性、 resources 插件资源过滤功能(filter)和 Maven 的 profile 功能,实现环境的灵活切换

属性

通过 properties 元素用户可以自定义一个或者多个 Maven 属性,然后在 pom 其他的地方使用 ${属性名} 的方式引用该属性,这种方式最大意义在于消除重复。

一、内置属性

  • ${basedir} 表示项目根目录,即包含 pom.xml 文件的目录
  • ${version} 等同于 或者{pom.version} 表示项目版本

二、POM 属性

所有 pom 中的元素都可以用 project. 例如 ${project.artifactId} 对应了 < project>元素的值。常用的 POM 属性包括:

  • ${project.build.sourceDirectory} : 项目的主源码目录,默认为 src/main/java/.
  • ${project.build.testSourceDirectory} : 项目的测试源码目录,默认为 /src/test/java/.
  • ${project.build.directory} : 项目构建输出目录,默认为 target/.
  • ${project.build.outputDirectory} : 项目主代码编译输出目录,默认为 target/classes/.
  • ${project.build.testOutputDirectory} : 项目测试代码编译输出目录,默认为 target/testclasses/.
  • ${project.groupId}: 项目的 groupId.
  • ${project.artifactId} : 项目的 artifactId.
  • ${project.version} : 项目的 version, 等同于 ${version}
  • ${project.build.finalName} : 项目打包输出文件的名称,默认为 ${project.artifactId}${project.version}

三、自定义属性

在 pom 中元素下自定义的 Maven 属性

<properties>
    <swagger.version>2.2.2</swagger.version>
</properties>
<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger2</artifactId>
    <version>${swagger.version}</version>
</dependency>

四、Settings 属性

所有用的的 settings.xml 中的设定都可以通过 settings。前缀进行引用与 POM 属性同理。

如 ${settings.localRepository} 指向用户本地仓库的地址

五、Java 系统属性

所有 Java 系统属性都可以使用 Maven 属性引用,例如 ${user.home} 指向了用户目录。

可以通过命令行 mvn help:system 查看所有的 Java 系统属性

六、环境变量属性

所有环境变量都可以使用以 env. 开头的 Maven 属性引用。例如 ${env.JAVA_HOME} 指代了 JAVA_HOME 环境变量的值。

也可以通过命令行 mvn help:system 查看所有环境变量。

七、父级工程属性

上级工程的 pom 中的变量用前缀 引用。上级工程的版本也可以这样引用{parent.version}

Profile

profile 特性可以让我们定义多个 profile,然后每个 profile 对应不同的激活条件和配置信息,从而达到不同环境使用不同配置信息的效果。

profile 可以在以下几个地方声明:

给大家的福利

零基础入门

对于从来没有接触过网络安全的同学,我们帮你准备了详细的学习成长路线图。可以说是最科学最系统的学习路线,大家跟着这个大的方向学习准没问题。

同时每个成长路线对应的板块都有配套的视频提供:

在这里插入图片描述

因篇幅有限,仅展示部分资料

网络安全面试题

绿盟护网行动

还有大家最喜欢的黑客技术

网络安全源码合集+工具包

所有资料共282G,朋友们如果有需要全套《网络安全入门+黑客进阶学习资源包》,可以扫描下方二维码领取(如遇扫码问题,可以在评论区留言领取哦)~

需要体系化学习资料的朋友,可以加我V获取:vip204888 (备注网络安全)

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化资料的朋友,可以点击这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
注:下文的 *** 代表文件名的组件名称。 # 包含: 文-英文对照文档:【***-javadoc-API文档-文(简体)-英语-对照版.zip】 jar包下载地址:【***.jar下载地址(官方地址+国内镜像地址).txt】 Maven依赖:【***.jar Maven依赖信息(可用于项目pom.xml).txt】 Gradle依赖:【***.jar Gradle依赖信息(可用于项目build.gradle).txt】 源代码下载地址:【***-sources.jar下载地址(官方地址+国内镜像地址).txt】 # 本文件关键字: 文-英文对照文档,英对照文档,java,jar包,Maven,第三方jar包,组件,开源组件,第三方组件,Gradle,文API文档,手册,开发手册,使用手册,参考手册 # 使用方法: 解压 【***.jar文文档.zip】,再解压其的 【***-javadoc-API文档-文(简体)版.zip】,双击 【index.html】 文件,即可用浏览器打开、进行查看。 # 特殊说明: ·本文档为人性化翻译,精心制作,请放心使用。 ·本文档为双语同时展示,一行原文、一行译文,可逐行对照,避免了原文/译文来回切换的麻烦; ·有原文可参照,不再担心翻译偏差误导; ·边学技术、边学英语。 ·只翻译了该翻译的内容,如:注释、说明、描述、用法讲解 等; ·不该翻译的内容保持原样,如:类名、方法名、包名、类型、关键字、代码 等。 # 温馨提示: (1)为了防止解压后路径太长导致浏览器无法打开,推荐在解压时选择“解压到当前文件夹”(放心,自带文件夹,文件不会散落一地); (2)有时,一套Java组件会有多个jar,所以在下载前,请仔细阅读本篇描述,以确保这就是你需要的文件;

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值