https://mp.weixin.qq.com/mp/appmsgalbum?__biz=MzA5MTkxMDQ4MQ==&action=getalbum&album_id=1318992648564424704&scene=173&from_msgid=&from_itemidx=&count=3&nolastread=1#wechat_redirect
11、SpringMVC 系列目录
- SpringMVC 系列第 1 篇:helloword
- SpringMVC 系列第 2 篇:@Controller、@RequestMapping
- SpringMVC 系列第 3 篇:异常高效的一款接口测试利器
- SpringMVC 系列第 4 篇:controller 常见的接收参数的方式
- SpringMVC 系列第 5 篇:@RequestBody 大解密,说点你不知道的
- SpringMVC 系列第 6 篇:上传文件的 4 种方式,你都会么?
- SpringMVC 系列第 7 篇:SpringMVC 返回视图常见的 5 种方式,你会几种?
- SpringMVC 系列第 8 篇:返回 json & 通用返回值设计
- SpringMVC 系列第 9 篇:SpringMVC 返回 null 是什么意思?
- SpringMVC 系列第 10 篇:异步处理
- SpringMVC 系列第 11 篇:集成静态资源
- SpringMVC 系列第 12 篇:拦截器
- SpringMVC 系列第 13 篇:统一异常处理
- SpringMVC 系列第 14 篇:实战篇:通用返回值 & 异常处理设计
- SpringMVC 系列第 15 篇:全注解的方式 & 原理解析
- SpringMVC 系列第 16 篇:通过源码解析 SpringMVC 处理请求的流程
- SpringMVC 系列第 17 篇:源码解析 SpringMVC 容器的启动过程
- SpringMVC 系列第 18 篇:强大的 RequestBodyAdvice 解密
- SpringMVC 系列第 19 篇:强大的 ResponseBodyAdvice 解密
- SpringMVC 系列第 20 篇:RestFull 详解
- SpringMVC 系列第 21 篇:接口调用过利器 RestTemplate
- SpringMVC 系列第 22 篇:参数解析器 HandlerMethodArgumentResolver 解密
- SpringMVC 系列第 23 篇:@RequestParam 用法及原理详解
- SpringMVC 系列第 24 篇:@RequestBody 用法及原理详解
- SpringMVC 系列第 25 篇:@RequestHeader 用法及原理详解
- SpringMVC 系列第 26 篇:@CookieValue 用法及原理详解
- SpringMVC 系列第 27 篇:@RequestAttribute 详解
- SpringMVC 系列第 28 篇:@SessionAttribute 详解
- SpringMVC 系列第 29 篇:重定向和转向详解
- SpringMVC 系列第 30 篇:Converter 转换器详解
- SpringMVC 系列第 31 篇:跨域问题详解
12、更多系列文章
- Spring 高手系列(共 56 篇)
- Java 高并发系列(共 34 篇)
- MySql 高手系列(共 27 篇)
- Maven 高手系列(共 10 篇)
- Mybatis 系列(共 12 篇)
- 聊聊 db 和缓存一致性常见的实现方式
- 接口幂等性这么重要,它是什么?怎么实现?
- 泛型,有点难度,会让很多人懵逼,那是因为你没有看这篇文章!
13、最新资料
- 尚硅谷 Java 学科全套教程(总 207.77GB)
- 2021 最新版 Java 微服务学习线路图 + 视频
- 阿里技术大佬整理的《Spring 学习笔记.pdf》
- 阿里大佬的《MySQL 学习笔记高清.pdf》
- 2021 版 java 高并发常见面试题汇总.pdf
- Idea 快捷键大全.pdf
我们只修改了b2b-account-api代码,所以我希望对这个重新打包,并且对这个有依赖的也重新打包,所以需要打包下面3个模块:
b2b-account-api
b2b-account-service
b2b-order-service
上面列表中的后面两个是依赖于b2b-account-api的,可以在b2b/pom.xml中执行下面命令:
mvn clean install -pl b2b-account/b2b-account-api -amd
需求:我们来构建b2b-order-service,希望b2b-account-service依赖的构件也能被同时构建,b2b-account-service依赖于b2b-account-api和b2b-order-api,可能b2b-account-service会依赖的更多。
可以使用下面命令:
mvn clean install -pl b2b-order/b2b-order-service -am
mvn clean install -rf b2b-order/b2b-order-service
-rf b2b-order/b2b-order-service对上面的反应堆构件顺序进行裁剪,将b2b-order/b2b-order-service前面的部分干掉,从b2b-order/b2b-order-service开始执行构建操作,所以剩下了3个需要构建的模块。
下面我们来看一下maven中不需要自定义的5类属性。
内置属性
${basedir}:表示项目根目录,即包含pom.xml文件的目录
${version}:表示项目的版本号
POM属性
用户可以使用该属性引用pom.xml文件中对应元素的值,例如${project.artifactId}就可以取到project->artifactId元素的值,常用的有:
${pom.build.sourceDirectory}:项目的主源码目录,默认为src/main/java/
${project.build.testSourceDirectory}:项目的测试源码目录,默认为src/test/java/
${project.build.directory}:项目构建输出目录,默认为target/
${project.build.outputDirectory}:项目主代码编译输出目录,默认为target/classes
${project.build.testOutputDirectory}:项目测试代码编译输出目录,默认为target/test-classes
${project.groupId}:项目的groupId
${project.artifactId}:项目的artifactId
${project.version}:项目的version,与${version}等价
${project.build.finalName}:项目打包输出文件的名称,默认为${project.artifactId}-${project.version}
Settings属性
这种属性以settings.开头来引用~/.m2/settings.xml中的内容,如:
${settings.localRepository}
指向用户本地仓库的地址。
java系统属性
所有java系统属性都可以使用maven属性来进行引用,例如${user.home}指向了当前用户目录。
java系统属性可以通过mvn help:system命令看到。
环境变量属性
所有的环境变量都可以使用env.开头的方式来进行引用,如:
${env.JAVA_HOME}
可以获取环境变量JAVA_HOME的值。
用户可以使用mvn help:system命令查看所有环境变量的值。
上面的maven属性,我们在pom.xml中通过${属性名称}可以灵活的引用,对我们写pom.xml文件帮助还是比较大的。
实操案例
将下面配置放在b2b-account-service/pom.xml中:
<properties>
<!-- 项目的主源码目录,默认为src/main/java/ -->
<a>${pom.build.sourceDirectory}</a>
<!-- 项目的测试源码目录,默认为src/test/java/ -->
<b>${project.build.testSourceDirectory}</b>
<!-- 项目构建输出目录,默认为target/ -->
<c>${project.build.directory}</c>
<!-- 项目主代码编译输出目录,默认为target/classes -->
<d>${project.build.outputDirectory}</d>
<!-- 项目测试代码编译输出目录,默认为target/test-classes -->
<e>${project.build.testOutputDirectory}</e>
<!-- 项目的groupId -->
<f>${project.groupId}</f>
<!-- 项目的artifactId -->
<g>${project.artifactId}</g>
<!-- 项目的version,与${version}等价-->
<h>${project.version}</h>
<!-- 项目打包输出文件的名称,默认为${project.artifactId}-${project.version} -->
<i>${project.build.finalName}</i>
<!-- setting属性 -->
<!-- 获取本地仓库地址-->
<a1>${settings.localRepository}</a1>
<!-- 系统属性 -->
<!-- 用户目录 -->
<a2>${user.home}</a2>
<!-- 环境变量属性,获取环境变量JAVA_HOME的值 -->
<a3>${env.JAVA_HOME}</a3>
</properties>
然后在b2b/pom.xml所在目录执行下面命令:
D:\code\IdeaProjects\b2b>mvn help:effective-pom -pl :b2b-account-service > 1.xml
上面这个命令会将mvn ...执行的结果输出到b2b/1.xml目录,mvn这段命令有看不懂的朋友,可以去看看前面的文章。
b2b目录中产生了一个1.xml,如下:

我们打开1.xml看一下,部分内容如下:
<properties>
<a>D:\code\IdeaProjects\b2b\b2b-account\b2b-account-service\src\main\java</a>
<a1>${settings.localRepository}</a1>
<a2>C:\Users\Think</a2>
<a3>D:\installsoft\Java\jdk1.8.0_121</a3>
<b>D:\code\IdeaProjects\b2b\b2b-account\b2b-account-service\src\test\java</b>
<b2>D:\code\IdeaProjects\b2b</b2>
<c>D:\code\IdeaProjects\b2b\b2b-account\b2b-account-service\target</c>
<d>D:\code\IdeaProjects\b2b\b2b-account\b2b-account-service\target\classes</d>
<e>D:\code\IdeaProjects\b2b\b2b-account\b2b-account-service\target\test-classes</e>
<f>com.javacode2018</f>
<g>b2b-account-service</g>
<h>1.0-SNAPSHOT</h>
<i>b2b-account-service-1.0-SNAPSHOT</i>
</properties>
设置资源文件内容动态替换
资源文件中可以通过${maven属性}来引用maven属性中的值,打包的过程中这些会被替换掉,替换的过程默认是不开启的,需要手动开启配置。
修改src/main/resource/jdbc.properties内容如下:
jdbc.url=${jdbc.url}
jdbc.username=${jdbc.username}
jdbc.password=${jdbc.password}
修改src/test/resource/jdbc.properties内容如下:
jdbc.url=${jdbc.url}
jdbc.username=${jdbc.username}
jdbc.password=${jdbc.password}
b2b-account-service/pom.xml中加入下面内容:
<properties>
<!-- 指定资源文件复制过程中采用的编码方式 -->
<encoding>UTF-8</encoding>
<jdbc.url>jdbc:mysql://localhost:3306/javacode2018?characterEncoding=UTF-8</jdbc.url>
<jdbc.username>root</jdbc.username>
<jdbc.password>root</jdbc.password>
</properties>
开启动态替换配置,需要在pom.xml中加入下面配置:
<build>
<resources>
<resource>
<!-- 指定资源文件的目录 -->
<directory>${project.basedir}/src/main/resources</directory>
<!-- 是否开启过滤替换配置,默认是不开启的 -->
<filtering>true</filtering>
</resource>
</resources>
<testResources>
<testResource>
<!-- 指定资源文件的目录 -->
<directory>${project.basedir}/src/test/resources</directory>
<!-- 是否开启过滤替换配置,默认是不开启的 -->
<filtering>true</filtering>
</testResource>
</testResources>
</build>
注意上面开启动态替换的元素是
filtering。上面build元素中的
resources和testResources是用来控制构建过程中资源文件配置信息的,比资源文件位于哪个目录,需要复制到那个目录,是否开启动态过滤等信息。
resources元素中可以包含多个resource,每个resource表示一个资源的配置信息,一般使用来控制主资源的复制的。
testResources元素和testResources类似,是用来控制测试资源复制的。.
自定义替换的分隔符
自定义分隔符,需要我们配置maven-resources-plugin插件的参数,如下:
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.6</version>
<configuration>
<!-- 是否使用默认的分隔符,默认分隔符是${*}和@ ,这个地方设置为false,表示不启用默认分隔符配置-->
<useDefaultDelimiters>false</useDefaultDelimiters>
<!-- 自定义分隔符 -->
<delimiters>
<delimiter>$*$</delimiter>
<delimiter>##</delimiter>
</delimiters>
</configuration>
</plugin>
</plugins>
delimiters中可以配置多个delimiter,可以配置#*#,其中的*表示属性名称,那么资源文件中的#属性名#在复制的过程中会被替换掉,*前后都是#,表示前后分隔符都一样,那么可以简写为#,所以#*#和#写法是一样的,我们去看一下源码,delimiters的默认值如下:
this.delimiters.add("${*}");
this.delimiters.add("@");
如果我们不想让cont.properties被复制到target/classes目录,我们怎么做?我们需要在资源构建的过程中排除他,可以使用exclude元素信息进行排除操作。
修改pom.xml中resources元素配置如下:
<resources>
<resource>
<!-- 指定资源文件的目录 -->
<directory>${project.basedir}/src/main/resources</directory>
<!-- 是否开启过滤替换配置,默认是不开启的 -->
<filtering>true</filtering>
<includes>
<include>**/jdbc.properties</include>
</includes>
<excludes>
<exclude>**/const.properties</exclude>
</excludes>
</resource>
</resources>
上面使用
includes列出需要被处理的,使用excludes排除需要被处理的资源文件列表,采用通配符的写法,**匹配任意深度的文件路径,*匹配任意个字符。
通过maven属性来控制环境的开启
刚才上面说了通过-P profileId的方式来指定环境,现在我们想通过自定义的属性值来控制使用哪个环境。
可以在profile元素中加入下面配置
<activation>
<property>
<name>属性xx</name>
<value>属性xx的值</value>
</property>
</activation>
那么我们可以在mvn后面跟上下面的命令可以开启匹配的环境:
mvn ... -D属性xx=属性xx的值
-D可以通过命令行指定一些属性的值,这个前面有讲过,-D后面的属性会和activation->properties中的name、value进行匹配,匹配成功的环境都会被开启。
新问题:配置太分散了
我们的系统中有2个模块需要用到数据库的配置,这两个模块是:
b2b-account-service
b2b-order-service
上面我们介绍了b2b-account-service不同环境的构建操作,是在pom.xml中进行配置的,b2b-order-service中数据的配置也可以这么做,如果以后有更多的模块都需要连接不同的数据库,是不是每个模块中都需要配置这样的pom.xml,那时候数据库的配置分散在几十个pom.xml文件中,如果运维需要修改数据库的配置的时候,需要去每个模块中去修改pom.xml中的属性,这种操作会让人疯掉的,我们可以怎么做?
我们可以将数据库所有的配置放在一个文件中,运维只用修改这一个文件就行了,然后执行构件操作,重新发布上线,就ok了。
maven支持我们这么做,可以在profile中指定一个外部属性文件xx.properties,文件内容是这种格式的:
key1=value1
key2=value2
keyn=value2
然后在profile元素中加入下面配置:
<build>
<filters>
<filter>xx.properties文件路径(相对路径或者完整路径)</filter>
</filters>
</build>

ArrayList的subList方法,返回的是原集合的一个子集合(视图),非结构性修改任意一个集合的元素的值,都会彼此影响,结构性修改原集合时,会报ConcurrentModificationException异常,结构性修改子集合时,会影响原集合,所以使用时要注意,避免程序错误或者异常。
Hutool 工具箱
小而全的Java工具类库 Hutool (核心篇) - 残城碎梦 - 博客园 (cnblogs.com)
【Python微信机器人】第六篇:优化使用方式,可pip安装 - Python成长路 - 博客园 (cnblogs.com)
[Python学习笔记]制作自动将xls文件转化为xlsx文件的程序 - 紫色天空玫玫 - 博客园 (cnblogs.com)
【GUI软件】小红书搜索结果批量采集,支持多个关键词同时抓取! - 马哥python说 - 博客园 (cnblogs.com)
玩转Spring状态机 - 京东云开发者 - 博客园 (cnblogs.com)
我试图通过这篇文章,教会你一种阅读源码的方式。 (qq.com)
我是真没想到,这个面试题居然从11年前就开始讨论了,而官方今年才表态。 (qq.com)
如果让你来设计网络 (qq.com)
一个注解实现接口幂等性,真心优雅! - Java技术栈 - 博客园 (cnblogs.com)
浙公网安备 33010602011771号