maven 镜像仓库与资源文件

仓库镜像mirrors

      如果仓库X可以提供仓库Y存储的所有内容,那么就可以认为X是Y的一个镜像。换句话说,任何一个可以从仓库Y获取的构建,都在够从它的镜像中获取。举个例子,http://maven.net.cn/content/groups/public/是中央仓库http://repo1.maven.org/maven2/在中国的镜像,由于地理位置,该镜像往往能够提供比中央仓库更快的服务,因此,可以配置Maven使用该镜像来代替中央仓库。编辑settings.xml文件。

<settings>

……

<mirrors>

<mirror>

<id>maven.net.cn</id>

<name>oneof the central mirrors in china</name>

<url>http://maven.net/content/groups/public/</url>

<mirrorOf>central</mirrorOf>

</mirror>

</mirrors>

….

</settings>

该配置中,<mirrorOf>的值为central,表示该配置为中央仓库的镜像,任何对于中央仓库的请求都会转至该镜像,用户也可以使用同样的方法配置其它仓库的镜像。另外三个元素id、name、url与一般仓库配置无异,表示该仓库的唯一标识符、名称以及地址。类似地,如果该镜像需要认证,那基于该id配置仓库认证,如下配置:

<settings>

….

<server>

      <id>maven.net.cn</id>

      <username>admin</username>

      <password>******</password>

    </server>

….

</settings>

关于镜像的一个更加常用的做法是结合私服。由于私服可以代理任何外部公共仓库(包括中央仓库),因此,对于组织内部的maven用户来说,使用一个私服地址就等于使用了所有需要的外部仓库,这可以将配置集中到私服,从而简化了maven本身的配置。在这种情况下,任何需要的构建都可以从私服获得,私服就是所有仓库的镜像仓库。我们可以配置这样的一个镜像,如下配置:

      <settings>

……

<mirrors>

<mirror>

<id>internal-repository</id>

<name>internalrepository manager</name>

<url>http://192.168.1.112:8081/nexus/content/groups/public</url>

<mirrorOf>*</mirrorOf>

</mirror>

</mirrors>

….

</settings>

该例中<mirrorOf>的值为星号,标识该配置是所有的maven仓库的镜像,任何对于远程仓库的请求都会转至http://192.168.1.112:8081/nexus/content/groups/public。如果该镜像仓库需要认证,则配置id为internal-repository的<server>即可。

Maven还支持更高级的镜像配置:

<mirrorOf>*</mirrorOf>:匹配所有远程仓库

<mirrorOf>external:*</mirrorOf>:除了localhost与file://协议的地址,匹配所有的远程仓库,也就是说,匹配所有不在本机上的远程仓库

<mirrorOf>repo1,repo2</mirrorOf>:匹配仓库repo1和repo2,使用逗号分隔多个远程仓库

<mirrorOf>*,!repo1</mirrorOf>:除了repo1外,匹配所有远程仓库,使用感叹号将仓库从匹配中移除。

需要注意的是,由于镜像仓库完全屏蔽了被镜像仓库,当镜像仓库不稳定或者停止服务的时候,maven仍将无法访问被镜像仓库,因而将无法下载构建。


配置properties属性

通过在pom.xml配置<properties>元素,用户可以自定义一个或者多个maven属性,然后再pom的其它地方使用${属性名称}的方式引用该属性,这个做法的最大意义在于消除重复。如,本来需要在多个地方重复声明同样的SpringFramework版本,现在只在一个地方声明就可以,重复越多,好处就越明显。因为这样不仅减少了日后升级版本的工作量,也能降低错误发生的概率。我们来看下配置:

<project>

….

  <properties>

<springframework.version>4.1.1.RELEASE</springframework.version>

</properties>

  <dependencies>

 <dependency>

<groupId>org.springframework</groupId>

<artifactId>spring-core</artifactId>

<version>${springframework.version}</version>

</dependency>

<dependency>

<groupId>org.springframework</groupId>

<artifactId>spring-beans</artifactId>

<version>${springframework.version}</version>

</dependency>

    </dependencies>

….

</project>

 

内置属性:主要有两个常用内置属性:

${basedir}标识项目的根目录,即包含pom.xml文件的目录;${version}表示项目版本

pom属性:用户可以使用该类属性引用pom文件中对应元素的值。例如:${project.artifactId}就对应了<project><artifactId>元素的值,常用的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.finalName}:项目打包输出文件的名称,默认为:${project.artifactId}-${project.version}。

这些属性都对应一个pom元素,他们中一些属性的默认值都是在超级pom中定义的,

1)自定义属性:用户可以在POM的<properties>元素下自定义Maven属性,例如:

<project>

<properties>

<my.prop>hello</my.prop>

</properties>

….

</project>

然后再pom中其它地方使用${my.prop}的时候会被替换成hello。

2)Settings属性:与POM属性同理,用户使用以settings.开头的属性引用settings.xml文件中xml元素的值,如常用的${settings.localRepository}指向用户本地仓库的地址

3)java系统属性:所有java系统属性都可以使用maven属性引用,例如${user.home}指向了用户目录。用户可以使用mvn help:system查看所有的java系统属性

4)环境变量属性:所有环境变量都可以使用env.开头的maven属性引用。例如${env.JAVA_HOME}指向了JAVA_HOME环境变量的值。用户可以使用mvn help:system查看所有环境变量


在一个多模块项目中,模块之间的依赖比较常见,这些模块通常会使用桐乡的groupId和version。因此这个时候就可以使用POM属性,如配置:

<dependencies>

<dependency>

       <groupId>${project.groupId}</groupId>

       <artifactId>module-task_one</artifactId>

       <version>${project.version}</version>

    </dependency>

<dependency>

       <groupId>${project.groupId}</groupId>

        <artifactId>module-task-two</artifactId>

       <version>${project.version}</version>

    </dependency>

</dependencies>

在配置中,当前模块依赖于module-task-one和module-task-two,这三个模块使用同样的groupId和version,因此可以在依赖配置中使用POM属性${project.groupId}和${project.version},表示这两个依赖的groupId和version与当前模块一致。这样,当项目版本升级的时候,就可以不再需要更改依赖的版本了。

大量的maven插件用到了maven属性,这意味着在配置插件的时候同样可以使用maven属性来方便的自定义插件行为。如:maven-surefire-plugin运行后默认的测试报告目录为target/surefire-reports,这个实际上就是${project.build.directory}/surefire-reports,如果查阅该插件的文档,会发现该插件提供了reportsDirectory参数来配置测试报告目录。因此如果想要修改测试报告目录,例如改成target/test-reports,就可以按照如下配置:

<plugin>

<groupId>org.apache.maven.plugins</groupId>

<artifactId>maven-surefire-plugin</artifactId>

<version>2.5</version>

<configuration>

<reportsDirectory>${project.build.directory}/test-reports</reportsDirectory>

</configuration>

</plugin>

 

资源过滤profile

为了应对环境的变化,首先需要使用maven属性将这些将会发生变化的部分提取出来。如在连接数据库使用的驱动类、URL、用户名和密码都可以发生变化,因此用maven属性取代它们:

Database.jdbc.DriverClass= ${db.driver}

Database.jdbc.connectionURL= ${db.url}

Database.jdbc.username= ${db.username}

Database.jdbc.password= ${db.password}

这里定义了四个maven属性:db.driver、db.url、db.username、db.password,它们的命名是任何的,可以根据自己的实际情况定义合适的属性名称。

既然使用了maven属性,就应该在某个地方定义它们。前面我们介绍过使用maven属性,这里介绍另外一种方式,使用一个额外的profile将其包裹,如下:

<profiles>

<profile>

<id>dev</id>

<properties>

<db.driver>con.mysql.jdbc.Driver</db.driver>

<db.url>jdbc:mysql://192.168.1.111:3306/test</db.url>

<db.username>dev</db.username>

<db.password>pass</db.password>

</ properties>

</profile>

</profiles>

 

上面定义的配置跟pom.xml下直接定义properties元素并无二致,这里只是使用了一个id为dev的profile属性,其目的是将开发环境下的配置与其它环境区别开来。我们来详细解释下profile。

有了属性定义,配置文件中也使用了这些属性,一切OK了吗?还不行。需要留意的是,maven属性默认只有在pom中才会被解析。也就是说,${db.username}放到pom中会变成test,但是如果放到src/man/resources/目录下的文件中,构建的时候它仍然还是${db.username}。因此,需要让maven解析资源文件中的maven属性。

资源文件的处理其实就是maven-resources-plugin做的事情,它默认的行为只是将项目主资源文件复制到主代码编译输出目录,将测试资源文件复制到测试代码的编译输出目录中。不过只要通过一些配置,该插件就能够解析资源文件中的maven属性,即开始资源过滤。

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

<project>

......

<build>

<resources>

<resource>

<directory>${project.basedir}/src/main/resources</directory>

<filtering>true</filtering>

</resource>

</resources>

</build>

....

</project>

 

类似地,配置测试资源目录过滤

<testResources>

<testResource>

<directory>${project.basedir}/src/test/resources</directory>

<filtering>true</filtering>

</testResource>

</testResources>

 

我们还可以为每个资源目录提供不同的过滤配置,如下配置

<resources>

<resource>

<directory>${project.basedir}/src/main/resources</directory>

<filtering>true</filtering>

</resource>

<resource>

<directory>${project.basedir}/src/main/sql</directory>

<filtering>false</filtering>

</resource>

</resources>

如上配置了两个资源目录,其中src/main/resources开启了过滤,而src/main/sql没有启动过滤。

到目前为止一切基本就绪了,我们将数据库配置的变化部分提取成了maven属性,在pom的profile中定义了这些属性的值,并且为资源目录开启属性过滤。最后,只需要在命令行激活profile,maven就能够在构建项目的时候使用profile中属性值替换数据库配置文件中的属性引用。

$mvn cleaninstall –Pdev

Mvn的-P参数标识在命令行激活一个profile。这里激活了id为dev的profile。构建完成后,输出目录中的数据库配置就是一个开发环境的配置了:

Database.jdbc.DriverClass= com.mysql.jdbc.Driver

Database.jdbc.connectionURL= jdbc:mysql://localhost:3306/test

Database.jdbc.username= dev

Database.jdbc.password= pass

从上面内容我们看到,不同环境的构建很可能死不同的,典型的情况就是数据库配置。初次之外,有些环境可能需要配置插件使用恩地文件,或者使用特殊版本的依赖,或者需要一个特殊的构建名称。要想使得一个构建不做任何修改就能在任何环境下运行,往往是不可能的。为了能让构建在各个环境下方便的移植,maven引入了profile的概念。Profile能够在构建的时候修改pom的一个子集,或者添加额外的配置元素。用户可以使用很多方式激活profile,以实现构建在不同的环境下的移植。

 

针对不同环境的profile

上面我们引入一个针对开发环境的profile,类似地加入测试环境和产品环境的profile,如:

<profiles>

<profile>

<id>dev</id>

<properties>

<db.driver>con.mysql.jdbc.Driver</db.driver>

<db.url>jdbc:mysql://192.168.1.111:3306/test</db.url>

<db.username>dev</db.username>

<db.password>pass</db.password>

</ properties>

</profile>

 

<profile>

<id>test</id>

<properties>

<db.driver>con.mysql.jdbc.Driver</db.driver>

<db.url>jdbc:mysql://192.168.1.112:3306/test</db.url>

<db.username>test</db.username>

<db.password>pass</db.password>

</ properties>

</profile>

</profiles>

同样的属性在两个profile中的值是不一样的,dev profile提供了开发环境数据库的配置,而test profile提供了测试环境数据库的配置。类似的,我们还可以添加一个基于产品的数据库配置。

现在,开发人员可以在使用mvn命令的时候再后面加上-Pdev激活dev profile,而测试人员使用-Ptest激活test profile

 

激活profile

1)命令行激活:用户可以使用mvn命令行参数-P加上profile的id来激活profile,多个id之间以逗号分隔。如:下面的命令激活了dev-x和dev-y两个profile:

$mvn clean install –Pdev –x,dev –y

2) settings文件显示激活:如果希望某个profile默认就一直处于激活状态,我们可以配置settings.xml文件的active-Profiles元素,标识其配置在profile对于所有项目都处于激活状态,如下配置:

<settings>

….

<activeProfiles>

   <activeProfile>dev</activeProfile>

 </activeProfiles>

</settings>

3)系统属性激活:我们还可以配置当某个系统属性存在的时候,自动激活profile,如下配置:

<profiles>

<profile>

<activation>

<property>

<name>test</name>

</property>

</activation>

</profile>

</profiles>

还可以进一步配置当某系统属性test存在,且值等于x的时候激活profile,如:

<profiles>

<profile>

<activation>

<property>

<name>test</name>

<value>x</value>

</property>

</activation>

</profile>

</profiles>

不要忘了,用户可以在命令行生命系统属性。如:

$mvn cleaninstall –Dtest = x

因此,这其实也是一种从命令行激活profile的方法,而且多个profile完全可以使用同一个系统属性来激活

4)操作系统环境激活:profile还可以自动根据操作系统环境激活,如果构建在不同的操作系统有差异,我们完全可以将这些差异写进profile,然后配置他们自动基于操作系统环境激活,如:

 <profiles>

<profile>

<activation>

<os>

<name>Windows 7</name>

<family>Windows</family>

<arch>x86</arch>

<version>5.1.2600</version>

</os>

</activation>

</profile>

</profiles>

这里family的值包括Windows/UNIX/Mac等,而其他几项name、arch、version,我们可以查看环境中的系统属性os.name、os.arch、os.version获取

5)文件存在与否获取:maven能够根据项目中某个文件存在与否决定是否激活,如:

 <profiles>

<profile>

<activation>

<file>

<missing>x.properties</missing>

<exists>y.properties</exists>

</file>

</activation>

</profile>

</profiles>

6)默认激活:我们可以定义profile的时候制定其默认激活,如:

 <profiles>

<profile>

<activation>

<activeByDefault>true</activeByDefault>

</activation>

</profile>

</profiles>

使用activeByDefault元素用户可以指定profile自动激活。不过需要注意的是,如果pom中有任何一个profile通过以后其它任何一种方式被激活了,所有的默认激活配置都会失效。

如果项目中有很多profile,他们的激活方法各异,我们怎么知道哪些profile被激活了呢?maven-help-plugin提供了一个目标版主用户了解当前激活的profile:

$mvnhelp:active-profiles

Maven-help-plugin还有另外一个目标用来列出当前所有的profile:

$mvnhelp:all-profiles

 

Profile种类:

根据具体的需要,可以在一下位置声明profile:

1)pom.xml:很显然,pom.xml中声明的profile只对当前项目有效

2)settings.xml:用户目录下.m2/settings.xml中的profile对本机上该用户所有的maven项目有效

3)全局setting.xml:maven安装目录下conf/settings.xml中的profile对本机上所有的maven项目有效

4)profiles.xml(maven2):还可以在项目根目录下使用一个额外的profiles.xml文件来声明profile,不过该特性在maven3移除,建议将这类profile移植到settings.xml中。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值