Maven Dependency

时间:2025-03-22 21:35:10
 
 
Dependency Management
在parent pom里使用< dependencyManagement>来简化dependency设置。举个例子:
Project A:
<project>
 ...
 <dependencies>
    <dependency>
      <groupId>group-a</groupId>
      <artifactId>artifact-a</artifactId>
      <version>1.0</version>
      <exclusions>
        <exclusion>
          <groupId>group-c</groupId>
          <artifactId>excluded-artifact</artifactId>
        </exclusion>
      </exclusions>
    </dependency>
    <dependency>
      <groupId>group-a</groupId>
      <artifactId>artifact-b</artifactId>
      <version>1.0</version>
      <type>bar</type>
      <scope>runtime</scope>
    </dependency>
 </dependencies>
</project>
 
Project B:
<project>
 ...
 <dependencies>
    <dependency>
      <groupId>group-c</groupId>
      <artifactId>artifact-b</artifactId>
      <version>1.0</version>
      <type>war</type>
      <scope>runtime</scope>
    </dependency>
    <dependency>
      <groupId>group-a</groupId>
      <artifactId>artifact-b</artifactId>
      <version>1.0</version>
      <type>bar</type>
      <scope>runtime</scope>
    </dependency>
 </dependencies>
</project>
 
下面通过在parent pom里使用< dependencyManagement>来管理child pom要使用的dependencies。
Parent Project:
<project>
 ...
 <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>group-a</groupId>
        <artifactId>artifact-a</artifactId>
        <version>1.0</version>
 
        <exclusions>
          <exclusion>
            <groupId>group-c</groupId>
            <artifactId>excluded-artifact</artifactId>
          </exclusion>
        </exclusions>
 
      </dependency>
 
      <dependency>
        <groupId>group-c</groupId>
        <artifactId>artifact-b</artifactId>
        <version>1.0</version>
        <type>war</type>
        <scope>runtime</scope>
      </dependency>
 
      <dependency>
        <groupId>group-a</groupId>
        <artifactId>artifact-b</artifactId>
        <version>1.0</version>
        <type>bar</type>
        <scope>runtime</scope>
      </dependency>
    </dependencies>
 </dependencyManagement>
</project>
 
使用上面parent pom就会简化child pom的dependency设置:
<project>
 ...
 <dependencies>
    <dependency>
      <groupId>group-a</groupId>
      <artifactId>artifact-a</artifactId>
    </dependency>
 
    <dependency>
      <groupId>group-a</groupId>
      <artifactId>artifact-b</artifactId>
      <!-- This is not a jar dependency, so we must specify type. -->
      <type>bar</type>
    </dependency>
 </dependencies>
</project>
 
注意:在上面的dependency引用中,非jar的必须使用<type> element。
Dependency management的另一个很有用的用处就是控制dependency的版本。还是举例:
Project A:
<project>
 <modelVersion>4.0.0</modelVersion>
 <groupId>maven</groupId>
 <artifactId>A</artifactId>
 <packaging>pom</packaging>
 <name>A</name>
 <version>1.0</version>
 <dependencyManagement>
   <dependencies>
     <dependency>
       <groupId>test</groupId>
       <artifactId>a</artifactId>
       <version>1.2</version>
     </dependency>
     <dependency>
       <groupId>test</groupId>
       <artifactId>b</artifactId>
       <version>1.0</version>
       <scope>compile</scope>
     </dependency>
     <dependency>
       <groupId>test</groupId>
       <artifactId>c</artifactId>
       <version>1.2</version>
       <scope>compile</scope>
     </dependency>
     <dependency>
       <groupId>test</groupId>
       <artifactId>d</artifactId>
       <version>1.2</version>
     </dependency>
   </dependencies>
 </dependencyManagement>
</project>
 
Project B:
<project>
 <parent>
    <artifactId>A</artifactId>
    <groupId>maven</groupId>
    <version>1.0</version>
 </parent>
 <modelVersion>4.0.0</modelVersion>
 <groupId>maven</groupId>
 <artifactId>B</artifactId>
 <packaging>pom</packaging>
 <name>B</name>
 <version>1.0</version>
 <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>test</groupId>
        <artifactId>d</artifactId>
        <version>1.0</version>
      </dependency>
    </dependencies>
 </dependencyManagement>
 <dependencies>
    <dependency>
      <groupId>maven-test</groupId>
      <artifactId>a</artifactId>
      <version>1.0</version>
      <scope>runtime</scope>
    </dependency>
    <dependency>
      <groupId>maven-test</groupId>
      <artifactId>c</artifactId>
      <scope>runtime</scope>
    </dependency>
 </dependencies>
</project>
 
上面可以看出project A是project B的parent,A和B都定义a, c, d dependencies,那么如果对project B执行maven命令,会采用哪个定义的呢?答案如下:
dependency a and c将会采用1.0版本。尽管在parent project A里定义的a and d的版本是1.2,但根据dependency mediation "nearest definition"特性,采用的是project B定义的版本。
dependency b只在parent project A里有定义,因此就采用project A的定义。即使Dependency c会使用不同版本的b, 如果执行project B还是会采用project A定义的版本(还是根据dependency mediation "nearest definition"特性)。
dependency d的情况和dependency b的差不多:由于它在A和B都用定义,因此是采用project B定义的版本1.0。假如Dependency c会使用不同版本的d, 如果执行project B还是会采用project B定义的版本(还是根据dependency mediation "nearest definition"特性)。
System scope Dependency
System scope的dependencies总是available的,而且不需要从repository里获取,因为定义成system scope的dependencies都是由JDK or VM提供的。典型的例子就是JDBC standard extensions和Java Authentication and Authorization Service (JAAS).
例子:
<project>
 ...
 <dependencies>
    <dependency>
      <groupId></groupId>
      <artifactId>jdbc-stdext</artifactId>
      <version>2.0</version>
      <scope>system</scope>
      <systemPath>${}/lib/</systemPath>
    </dependency>
 </dependencies>
 ...
</project>
如果你的artifact来自JDK's ,那么system path应该定义为:
<project>
 ...
 <dependencies>
    <dependency>
      <groupId></groupId>
      <artifactId>tools</artifactId>
      <version>1.5.0</version>
      <scope>system</scope>
      <systemPath>${}/../lib/</systemPath>
    </dependency>
 </dependencies>
 ...
</project>
 
 
 
Repository介绍
 
Artifact Repositories
Repository就是用来存储artifacts and dependencies(实质也就是artifact)的地方。
有2种类型的repositories: local and remote。local repository里存储了因有使用需要而从remote repository下载的artifacts 的cache,还存储了你在本地build的,但还没有发布到remote repository的artifacts。
Remote repositories能够被accessed by 各种协议(如file:// and http://)。Remote repositories可以是真正供所有人都可以进入的repositorie(例如:Maven's central repository  就是典型例子),也可以是一个build在你公司内部http server的internal repositories,它只在你们的开发团队里共享。
The local and remote repositories的结构是相同的,但作为maven的使用者,我们不需要去深入了解它的结构。
 
Why not Store JARs in CVS?
Maven强烈建议不要在你的project里包含任何要引用的JARs,即project不要存储这些jars,而应该定义对这些jars的dependency。例如,很多的project都会使用到一些常用的jar(如junit, XML parsers和standard utilities),你不要把他们的jar都放入你的project里,而应该使用它们的dependencies。
这些dependencies存储在local repositoty里可以供成千上万个project使用,其好处有:
·         It uses less storage – 每个JAR只存储在repository一个地方,所有的project如果要使用它就定义它的dependency即可,节约了空间,同时也使你的project cleaner。
·         It makes checking out a project quicker - initial checkout, and to a small degree updating, a project will be faster if there are no large binary files in CVS. While they may need to be downloaded again afterwards anyway, this only happens once and may not be necessary for some common JARs already in place.
·         No need for versioning – CVS and other source control systems are designed for versioning files, but external dependencies typically don't change, or if they do their filename changes anyway to indicate the new version. Storing these in CVS doesn't have any added benefit over keeping them in a local artifact cache.
 
Using Repositories
通常,你不需要对local repository做任何事,除非你想重新download所有的artifact而清空local repository
而对于remote repositories, 它们是用来download and upload artifact的 (当然,你必须有权限才可以操作).
Downloading from a Remote Repository
当一个project定义的dependency 在local repository里找不到,或者remote repository包含了新版本时,就会激活Download the dependency from remote repository的操作。
缺省情况下,会从maven central repository (/maven2 ) 下载。如果你还希望能够从其他的remote repository下载(比如要下载只供你们team使用的artifact),你需要在里做下列设置:
<project>
 ...
 <repositories>
    <repository>
      <id>my-internal-site</id>
      <url>http://myserver/repo</url>
    </repository>
 </repositories>
 ...
</project>
上述设置也可以在里。
Using Mirrors for the Central Repository
就象web server一样,central repository有时也会down机。如果这种情况发生了,你可以在 里设置 <mirrors> element。详见Using Mirrors for Repositories .
 
Build Offline
如果你在使用maven build project时你的电脑无法连上网,那么你可以在mvn命令里添加-o参数
 mvn -o package
但要注意:许多plugins在设置为offline的情况下不会执行任何需要连接上网的操作,就会导致失败。
 
Internal Repositories
 
对于团队合作开发的project,建一个internal repository,使得团队成员能够共享、下载、上传最新的artifact,是非常必要的。internal repository并没有什么特别,它实际上就是一个remote repository
团队成员可以使用HTTP or the file system (using a file:// URL)的方式从internal repository下载artifact,也可以使用 SCP, FTP, or a file copy的方式上传artifact到internal repository。
之后会有一篇文章专门讲如何set up, use and deploy internal repository.