目录

Maven笔记

Transitive Dependencies(Maven依赖可传递性)

这里是官网地址,本人英语渣渣,依靠翻译软件勉勉强强看懂,就不翻译出来班门弄斧了,请大家八仙过海各显神通

Maven avoids the need to discover and specify the libraries that your own dependencies require by including transitive dependencies automatically.

This feature is facilitated by reading the project files of your dependencies from the remote repositories specified. In general, all dependencies of those projects are used in your project, as are any that the project inherits from its parents, or from its dependencies, and so on.

There is no limit to the number of levels that dependencies can be gathered from. A problem arises only if a cyclic dependency is discovered.

With transitive dependencies, the graph of included libraries can quickly grow quite large. For this reason, there are additional features that limit which dependencies are included:

  • Dependency mediation

    - this determines what version of an artifact will be chosen when multiple versions are encountered as dependencies. Maven picks the “nearest definition”. That is, it uses the version of the closest dependency to your project in the tree of dependencies. You can always guarantee a version by declaring it explicitly in your project’s POM. Note that if two dependency versions are at the same depth in the dependency tree, the first declaration wins.

    • “nearest definition” means that the version used will be the closest one to your project in the tree of dependencies. Consider this tree of dependencies:

      1
      2
      3
      4
      5
      6
      
        A
        ├── B
        │   └── C
        │       └── D 2.0
        └── E
            └── D 1.0
      

      In text, dependencies for A, B, and C are defined as A -> B -> C -> D 2.0 and A -> E -> D 1.0, then D 1.0 will be used when building A because the path from A to D through E is shorter. You could explicitly add a dependency to D 2.0 in A to force the use of D 2.0, as shown here:

      1
      2
      3
      4
      5
      6
      7
      8
      
        A
        ├── B
        │   └── C
        │       └── D 2.0
        ├── E
        │   └── D 1.0
        │
        └── D 2.0      
      
  • Dependency management - this allows project authors to directly specify the versions of artifacts to be used when they are encountered in transitive dependencies or in dependencies where no version has been specified. In the example in the preceding section a dependency was directly added to A even though it is not directly used by A. Instead, A can include D as a dependency in its dependencyManagement section and directly control which version of D is used when, or if, it is ever referenced.

  • Dependency scope - this allows you to only include dependencies appropriate for the current stage of the build. This is described in more detail below.

  • Excluded dependencies - If project X depends on project Y, and project Y depends on project Z, the owner of project X can explicitly exclude project Z as a dependency, using the “exclusion” element.

  • Optional dependencies - If project Y depends on project Z, the owner of project Y can mark project Z as an optional dependency, using the “optional” element. When project X depends on project Y, X will depend only on Y and not on Y’s optional dependency Z. The owner of project X may then explicitly add a dependency on Z, at her option. (It may be helpful to think of optional dependencies as “excluded by default.")

Although transitive dependencies can implicitly include desired dependencies, it is a good practice to explicitly specify the dependencies your source code uses directly. This best practice proves its value especially when the dependencies of your project change their dependencies.

For example, assume that your project A specifies a dependency on another project B, and project B specifies a dependency on project C. If you are directly using components in project C, and you don’t specify project C in your project A, it may cause build failure when project B suddenly updates/removes its dependency on project C.

Another reason to directly specify dependencies is that it provides better documentation for your project: one can learn more information by just reading the POM file in your project, or by executing mvn dependency:tree.

Maven also provides dependency:analyze plugin goal for analyzing the dependencies: it helps making this best practice more achievable.

Maven的六类属性,${project.basedir},${project.build.directory}

内置属性

主要有两个常用内置属性:basedir项目的根目录(包含pom.xml文件的目录),{version}项目版本

POM属性

用户可以使用该属性引用POM文件中对应元素的值,常用的POM属性包括:

${project.build.sourceDirectory}:项目的主源码目录,默认为 src/main/java

${project.build.testSourceDirectory}:项目的测试源码目录,默认为 src/test/java

${project.build.directory}:项目构件输出目录,默认为 target/

${project.outputDirectory}:项目主代码编译输出目录,默认为 target/classes/

${project.testOutputDirectory}:项目测试代码编译输出目录,默认为 target/test-classes/

${project.groupId}:项目的 groupId

${project.artifactId}:项目的 artifactId

project.version:项目的version,与{version}等价

*project.build.fianlName:*项目打包输出文件的名称。默认为{project.artifactId}-${project.version}

自定义属性

用户可以在POM的元素下自定义Maven属性

Settings属性

用户使用settings.开头的属性引用 settings.xml 文件中XML元素的值

Java系统属性

所有Java系统属性都可以使用Maven属性引用

环境变量属性

所有环境变量都可以使用以env.开头的Maven属性引用

在依赖中 使用pom变量

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
<dependencies>
    <dependency>
        <groupId>${project.groupId}</groupId>
        <artifactId>part-a</artifactId>
        <version>${project.version}</version>
    </dependency>
    <dependency>
        <groupId>${project.groupId}</groupId>
        <artifactId>part-b</artifactId>
        <version>${project-version}</version>
    </dependency>
</dependencies>
123456789101112

在插件中使用pom变量

1
2
3
4
5
6
7
8
9
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>2.5</version>
    <configuration>
        <repositoryDirectory>${project.build.directory}/test-reports</repositoryDirectory>
    </configuration>
</plugin>
12345678

自定义变量

1
2
3
4
5
6
7
8
 <properties>
     <db.driver>com.mysql.jdbc.Driver</db.driver>
     <db.url>jdbc:mysql://localhost:3360/test</db.url>
     <db.username>username</db.username>
     <db.password>password></db.password>
 </properties>
</profiles>
1234567

Maven属性默认只有在POM中才会被解析,因此需要让Maven解析资源文件中的Maven属性。Maven用maven-resources-plugin处理资源文件。它默认的行为只是将项目主资源文件复制到主代码编译输出目录中,将测试资源文件复制到测试代码编译输出目录中。

Maven默认的主资源目录和测试资源目录的定义是在超级POM中,要为资源目录开启过滤,只要在此基础上添加一行filtering配置即可。

Filtering是maven resource插件的功能,作用是用环境变量,pom文件里定义的属性和指定文件里的属性替换属性文件的占位符。(超级pom在 apache-maven-3.3.9\lib\maven-model-builder-3.3.9.jar\org\apache\maven\model\pom-4.0.0.xml)

resource元素的作用

C:\Program_Green\hugo_extended_0.82.0_Windows-64bit\sites\KKKPJSKEY's-Case-Archives\content\posts\Maven-Note\1.jpg

子工程获取父工程路径

尝试在每个pom中设置属性以查找主项目目录。 在父级:

1
2
3
<properties>
    <main.basedir>${project.basedir}</main.basedir>
</properties>

在子元素们身上:

1
2
3
<properties>
    <main.basedir>${project.parent.basedir}</main.basedir>
</properties>

在孙辈中:

1
2
3
<properties>
    <main.basedir>${project.parent.parent.basedir}</main.basedir>
</properties>

注意

由于maven插件的生命周期原因,传递给子模块basedir属性为子模块属性,类似懒加载,传递至子目录才读取值,故需要添加parent,且忽略编译异常。此属性禁止在父POM工程中使用,仅允许传递给子模块使用。

1
2
3
4
5
<jar.target>D:/tmp/target</jar.target>
<!--suppress UnresolvedMavenProperty -->
<jar.target>${project.parent.basedir}/target/</jar.parent.target>
<!--suppress UnresolvedMavenProperty -->
<jar.target1>${project.parent.parent.basedir}/target/</jar.parent2.target>

这篇文章中有详细的例子

其他方式方法未验证,中文参考英文参考

打包过程排除文件夹

排除的文件夹位置src/main/dml

1
2
3
<excludes>
    <exclude>dml/**</exclude>
</excludes>

**注意:**避免使用<exclude>src/main/dml/**</exclude>会导致找不到

Windows环境下maven 安装与环境变量配置

Maven是一个项目管理的Java 工具,在JavaEE中,我们可以使用Maven方便地管理团队合作的项目,现在我们在学习JavaEE框架,使用Maven可以管理类库,有效方便地供团队中的其他人员使用。

一、下载 Maven

请访问Maven的下载页面:http://maven.apache.org/download.html,其中包含针对不同平台的各种版本的Maven下载文件。

注意:

/maven-note/2.png

/maven-note/3.png

我这里下载的是:apache-maven-3.3.9-bin.zip 版本。

二、解压 maven 压缩包。

解压apache-maven-3.1.1-bin.zip,并把解压后的文件夹下的apache-maven-3.1.1文件夹移动到E:\Maven 下,如果没有Maven 这个文件夹的话,请自行创建。

/maven-note/4.png

三、配置maven 的环境变量

右键“计算机”,选择“属性”,之后点击“高级系统设置”,点击“环境变量”,来设置环境变量,有以下系统变量需要配置:

新建系统变量 MAVEN_HOME 变量值: E:\Maven\apache-maven-3.3.9
编辑系统变量 Path 添加变量值: ;%MAVEN_HOME%\bin

/maven-note/5.png

/maven-note/6.png

注意:注意多个值之间需要有分号隔开,然后点击确定

四、检测是否安装成功。

最后检验配置是否成功:用win键+R,来打开命令行提示符窗口,即Dos界面,输入mvn --version若出现以下情况说明配置成功

/maven-note/7.png

或是输入:echo %M2_HOME%

查看版本:mvn -v

/maven-note/8.png

五、升级。

Maven还比较年轻,更新比较频繁,因此用户往往会需要更新Maven安装以获得更多更酷的新特性,以及避免一些旧的bu

只需要按照上面的配置过程换成新的包即可。

Maven配置阿里镜像仓库

打开maven的配置文件(windows机器一般在maven安装目录的conf/settings.xml),在<mirrors></mirrors>标签中添加mirror子节点:

1
2
3
4
5
6
<mirror>
    <id>aliyunmaven</id>
    <mirrorOf>*</mirrorOf>
    <name>阿里云公共仓库</name>
    <url>https://maven.aliyun.com/repository/public</url>
</mirror>

修改本地仓库的路径

另外最好修改本地仓库的路径,否则默认存储在C盘,容易占用过多。

<settings></settings>标签中添加localRepository子节点:

1
<localRepository>D:\repository</localRepository>