Maven进阶-属性与资源文件

一、属性

1. 简述

属性可以认为是声明在 pom 文档中的变量,当某一字段频繁出现在文档中时,将此字段声明为属性值则可以更便捷的编写与修改,属性的设置也能帮助开发者快速了解文档配置

属性常使用的方法是用来声明依赖的版本号,当项目存在大量依赖时,想要更改依赖的版本就不必挨个去找 version 标签了,只需要更改属性值即可

2. 属性的使用

(1)声明属性

属性需要被声明在 properties 标签中,每一个属性值都要用双标签包裹,标签名即为属性名,如下例:

<properties>
    <developer>mzz</developer>
    <updatetime>2022.08.29</updatetime>
    
    <spring.version>5.2.10.RELEASE</spring.version>
    <mybatis.version>3.5.10</mybatis.version>
</properties>

当然,属性并不只能用来声明版本号,任何你想设置的属性都可以

(2)引用属性值

使用 ${ },在大括号中包裹属性名即可引用属性值,如下例中的依赖版本号:

<dependencies>
	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-webmvc</artifactId>
		<version>${spring.version}</version>
	</dependency>

	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-jdbc</artifactId>
		<version>${spring.version}</version>
	</dependency>
</dependencies>

如我们熟知的 spring 相关的各种依赖,常常使用相同的版本,像这样配置以后,要修改版本只需更改 spring.version 的属性值即可,不必再更改各个依赖的 version 标签

3、补充

(1)每个 pom 文件中只能存在一个 properties 标签

每个 pom 文件中只能存在一个 properties 标签,设置属性出错的话记得检查下是不是有两个 properties

新建 maven 项目时,maven 自动生成的 pom.xml 文件中可能已经有了 properties 标签,里面写着文档编码,编译环境之类的信息,可以删去,也可以留着。删去之后,有时 maven 会报一个项目编码未设定的 warning,添加 project.build.sourceEncoding 属性,值为 UTF-8 即可

(2)属性值可以引用其他属性的值

如下例:

<properties>
	<first>${second}</first>
	<second>${third}</second>
	<third>3th</third>
</properties>

声明属性时,属性值可以引用其他属性,且不在意先后顺序,但不能闭环……

(3)后声明覆盖先声明

同一属性被多次声明,以最后一次声明为准

<properties>
	<username>Bob</first>
	<username>Alice</first>
</properties>
<!-- username 的值为 Alice -->

二、加载属性

1. 简述

这部分内容是写如何让配置文件能够读取 pom 文件中的属性值,比如数据库连接的用户名和密码,可以作为属性放在 pom 文件中,再由配置文件读取

看到这可能会有些疑惑,这样的属性值直接写在配置文件中不就好了吗,何必多次一举?事实上,这是为了后面的多环境开发做铺垫,因为不同的环境中这些属性的值可能会发生变化,此时来回更改配置文件就显得麻烦了,而我们按照环境分别设置属性值后,配置文件也会在不同环境下读取到对应的属性值,就不必更改配置文件

2. 加载属性的方法

(1)配置文件与属性

先来看一下 配置文件和 pom 中的属性值,如下

配置文件:

# ./src/main/resources/jdbc.properties
jdbc.driver=${jdbc.driver}
jdbc.url=${jdbc.url}
jdbc.username=${jdbc.username}
jdbc.password=${jdbc.password}

配置文件中读取属性依然用 ${ } 包裹属性名 (SpringBoot 项目中要用 @属性名@,${ }无效)

pom.xml 中的属性:

<properties>
    <jdbc.driver>com.mysql.cj.jdbc.Driver</jdbc.driver>
    <jdbc.url>jdbc:mysql://127.0.0.1:3306/db</jdbc.url>
    <jdbc.username>root</jdbc.username>
    <jdbc.password>123456</jdbc.password>
</properties>

(2)设置 resources 标签

接下来只需要在 pom 文件中配置 resources 属性,就能让 Maven 构建项目时对配置文件进行过滤,将属性替换成对应的值

resources 属性要写在 build 标签内,另外,看到 resources 这个复数形式的单词你就知道了,这里面还有若干个 resource 属性,resource 属性中包含 directory 属性和 filtering 属性,分别表示配置文件所在文件夹的相对路径,和过滤开关(设置为 true)。样例如下:

<build>
    <resources>
        <resource>
            <directory>src/main/resources</directory>
            <filtering>true</filtering>
        </resource>
    </resources>
</build>

(3)查看效果

项目构建之后,在 target/classes/ 目录下可以看到构建之后的资源文件

在这里插入图片描述
此时打开文件会发现里面的属性名已经被替换成了属性值

# ./src/main/resources/jdbc.properties
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://127.0.0.1:3306/db
jdbc.username=root
jdbc.password=123456

3. 补充

(1)${project.basedir} 属性

${project.basedir} 是 Maven 自动设置的内部属性,其值为此项目文件夹,也就是 pom.xml 所在的文件夹,directory 属性中经常以 ${project.basedir} 做前缀,表示在此项目内,如下例:

<build>
    <resources>
        <resource>
            <directory>${project.basedir}/src/main/resources</directory>
            <filtering>true</filtering>
        </resource>
    </resources>
</build>

可以发现,对应相对路径而言,路径中这个 ${project.basedir} 写不写是没有区别的……但写上可读性高一些,与 ${project.basedir} 类似的属性也很多,可以自行了解

(2)继承关系下的 resources

父模块中的 resources 属性会被继承给子模块,效果等同于将 resources 内的内容复制了一份给了子模块,而非是父模块中指定父模块内的文件夹,子模块中也指定父模块中的这个文件夹。

比如说父模块 A 中指定${project.basedir}是指项目文件夹 A,而继承给子模块 B 后,就变成了指定项目文件夹 B。

所以 resources 经常放在父模块中且配合 ${project.basedir} 使用,这样就相当于对每个子模块的资源做了处理

三、控制资源文件

引言

此时先提出一个问题,上面所说的 resources 中如果 filtering 的值为 false,那 resources 中的内容就没有作用了吗?或者说 resources 的作用只是为了让配置文件能够读取 pom 中的属性吗?

答案当然不是,事实上 resources 控制了项目中资源文件是否参与构建。不设置 resources 标签时,Maven 构建项目时会默认让 src/main/resources 目录下的所有资源文件参与构建,如果设置了 resources(且 directory 为 src/main/resources),那么效果和不设置 resources 一样……

但这是因为我们还没有了解 includes 和 excludes 两个属性,接下来看一下这两个属性的作用

1. includes 引入

includes 是 resources 中的属性,它会决定将 directory 文件夹下的哪些资源文件引入并参与构建,如果没有设置 includes 属性,那么 directory 内的所有文件都会被引入

<build>
    <resources>
        <resource>
            <directory>${project.basedir}/src/main/resources</directory>
            <includes>
			    <include>jdbc/</include>
				<include>*/mybatis-config.*</include>
			</includes>
        </resource>
    </resources>
</build>

includes 内的 include 表示要引入的文件路径,所有路径均在 directory 下,可以使用通配符,上例中的 * 表示匹配一个字段,效果如下图,引入了 jdbc 文件夹内的所有文件,和任意当前文件夹下的 mybatis-config 开头任意后缀名的文件

在这里插入图片描述

2. excludes 排除

excludes 和 includes 类似,只是效果相反,excludes 会将已引入的资源文件中排除指定的文件

<build>
    <resources>
        <resource>
            <directory>${project.basedir}/src/main/resources</directory>
            <excludes>
                <exclude>jdbc/jdbc2.*</exclude>
                <exclude>**/*.xml</exclude>
            </excludes>
        </resource>
    </resources>
</build>

效果如下图,由于未设置 includes,directory 文件夹内所有文件都被引入,而 excludes 排除了所有 jdbc 下 jdbc 开头任意后缀名文件,以及任意子文件夹下任意前缀的 .xml 文件,** 匹配所有子文件夹及文件,与 * 不同(* 只匹配一个字段,不能匹配子文件夹下的文件)

在这里插入图片描述

3. includes 和 excludes 同时使用

两个属性同时存在时,效果不变但顺序上,includes 先进行引入,excludes 再进行排除

<build>
    <resources>
        <resource>
            <directory>${project.basedir}/src/main/resources</directory>
            <includes>
                <include>jdbc/</include>
                <include>mybatis/</include>
            </includes>
            <excludes>
                <exclude>*/*2.*</exclude>
            </excludes>
        </resource>
    </resources>
</build>

如上例中,引入了 jdbc 和 mybatis 两个文件夹下的文件,又排除了任意当前文件夹下前缀以 2 结尾的任意后缀名的文件,效果如下图

在这里插入图片描述

此时应该明白了,filtering 属性的只设置为 true,是对参与构建的资源文件进行过滤,而文件是否参与构建,就是由 resources 属性控制着。无论 filtering 的值是什么,resources 都有它自己的作用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值