Spring Boot Maven Plugin
官方文档链接地址:http://docs.spring.io/spring-boot/docs/1.3.0.BUILD-SNAPSHOT/maven-plugin/index.html
第一部分
Spring Boot Maven Plugin提供了Spring Boot的Maven支持,允许你打包可执行文件和war文件,并且就地运行。
第一章 目标概述
Spring Boot Plugin有如下目标:
1.spring-boot:run 运行Spring Boot应用
2.spring-boot:repackage 重新打包jar/war包为可执行包
3.spring-boot:start 和spring-boot:stop 管理Spring Boot 应用的生命周期(即集成测试)
用法
关于如何使用Spring Boot Plugin的通用介绍可以在 第二章 章节中找到。一些更具体的用例在如下的例子中介绍。
用例
为了更好的理解Spring Boot的某些用法,可以参加如下章节例子。
1.自定义分类重打包
2.排除依赖
3.调试应用
4.随机端口集成测试
5.指定使用的(active)文件
第二章 目标
2.1插件文档
插件可使用目标如下:
| 目标 | 详情
|
| spring-boot:help | 展示spring-boot-maven-plugin的帮助信息,使用 mvn spring-boot:help -Ddetail=true -Dgoal=<goal-name>展示参数详情 |
| spring-boot:repackage | 重新打包存在的jar或者war包从而使他们可以在命令行使用jar -jar来执行,使用layout=NONE也可以简单的打包有嵌套依赖的jar(没有主类,所以无法执行)
|
| spring-boot:run | 运行一个可执行的应用 |
| spring-boot:start | 启动Spring应用程序。和run目标不同,该目标不会阻塞,并且允许其他目标来操作应用程序。这个目标通常是在应用程序集成测试套件开始之前和停止之后的继承测试脚本中使用
|
| spring-boot:stop | 停止使用start目标启动的spring应用程序,通常在测试套件完成后被调用。 |
2.2系统要求
Maven:2.0+
JDK:1.6+
Memory:没有最小限制
磁盘空间:没有最小限制
2.3用法
需要在项目插件配置中指定版本
在parent pom文件中配置插件管理
<pluginManagement>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>1.3.0.BUILD-SNAPSHOT</version>
</plugin>
</plugins>
</pluginManagement>
在parent pom文件或者在module的pom文件中配置插件如下:
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>1.3.0.BUILD-SNAPSHOT</version>
</plugin>
</plugins>
第三章:用法
插件提供了多个目标来与SpringBoot应用程序工作。
repackage:创建自动执行的jar包或者war包。它可以替代常规的构件或者连接到构建生命周期并有独立的分级。
run:运行SpringBoot应用程序,同时可以使用多个选项将参数传递给应用程序。
start和stop:集成spring boot应用程序到集成测试阶段,从而使应用程序在集成测试程序之前启动
3.1 重新打包应用
为了重新打包应用,只需要在pom文件中的plugin配置中如下:
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
上边重新打包jar和war包的例子是在Maven的package命令生命周期内构建的。包括所有的scope为provided的依赖。如果某些依赖需要被排除掉,可以使用exclude选项。具体参考 排除一个依赖 章节。
重新打包之后,默认情况下原始的(没有配置exectuable)构件(artifact)被重命名为.original,并且使用自定义的分级可以保持原始构件。
该构件重写了manifest,特别是它管理了之类和启动类条目。所以默认情况下不起作用你就必须配置这些条目(不是在jar插件中)。Main-Class实际上由boot插件的layout属性控制。
<pre style="font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none; padding: 9.5px; color: rgb(51, 51, 51); border-top-left-radius: 4px; border-top-right-radius: 4px; border-bottom-right-radius: 4px; border-bottom-left-radius: 4px; margin-top: 0px; margin-bottom: 10px; line-height: 20px; word-break: break-all; word-wrap: break-word; white-space: pre-wrap; border: 1px solid rgba(0, 0, 0, 0.14902); background-color: rgb(245, 245, 245);"><plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>1.3.0.BUILD-SNAPSHOT</version>
<configuration>
<mainClass>${start-class}</mainClass>
<layout>ZIP</layout>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin></pre>
3.2 运行应用程序
插件包含了一个run目标,该目标能够从命令行执行应用程序: mvn spring-boot:run
默认情况下,应用从Maven的JVM运行。如果需要在分支中运行,则指定fork选项。如果指定了jvmArguments或者agent参数,分支进程也会执行。
如果需要制定某些JVM参数(如为了debug),可以使用jvmArguments参数,更多细节参考 调试应用 一章。方便起见,为了启用总则(profiles),可以使用特定(profiles)属性来处理,参考 指定使用的配置文件 一章。
Spring Boot 1.3已经推出了devtools,它是提升使用Spring Boot应用开发时经验的一个模块。启用该模块,仅仅在项目中添加如下配置即可:
<pre style="font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none; padding: 9.5px; color: rgb(51, 51, 51); border-top-left-radius: 4px; border-top-right-radius: 4px; border-bottom-right-radius: 4px; border-bottom-left-radius: 4px; margin-top: 0px; margin-bottom: 10px; line-height: 20px; word-break: break-all; word-wrap: break-word; white-space: pre-wrap; border: 1px solid rgba(0, 0, 0, 0.14902); background-color: rgb(245, 245, 245);"><dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<version>1.3.0.BUILD-SNAPSHOT</version>
<optional>true</optional>
</dependency>
</dependencies></pre>
目前最新是2.0.0.BUILD-SNAPSHOT了。
当devtools运行时,会在重新编译应用时进行检测变化并且自动刷新。这不仅包括资源文件,也包括代码。它也提供了一个**的可以重加在的服务器,所以不管任何改变都会自动出发浏览器刷新。
devtools也可配置成仅仅静态资源改变时刷新浏览器(也就是忽略代码的改变),仅仅增加如下配置:
<pre style="font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none; padding: 9.5px; color: rgb(51, 51, 51); border-top-left-radius: 4px; border-top-right-radius: 4px; border-bottom-right-radius: 4px; border-bottom-left-radius: 4px; margin-top: 0px; margin-bottom: 10px; line-height: 20px; word-break: break-all; word-wrap: break-word; white-space: pre-wrap; border: 1px solid rgba(0, 0, 0, 0.14902); background-color: rgb(245, 245, 245);">spring.devtools.remote.restart.enabled=false</pre>
在devtools之前,该插件已经默认支持资源的及时刷新(hot refreshing),为了支持devtools功能,该插件功能已经被禁用。但是可以随时恢复该功能,恢复功能配置如下;
<pre style="font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none; padding: 9.5px; color: rgb(51, 51, 51); border-top-left-radius: 4px; border-top-right-radius: 4px; border-bottom-right-radius: 4px; border-bottom-left-radius: 4px; margin-top: 0px; margin-bottom: 10px; line-height: 20px; word-break: break-all; word-wrap: break-word; white-space: pre-wrap; background-color: rgb(245, 245, 245); border: 1px solid rgba(0, 0, 0, 0.14902);"><build>
...
<plugins>
...
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>1.3.0.BUILD-SNAPSHOT</version>
<configuration>
<addResources>true</addResources>
</configuration>
</plugin>
...
</plugins>
...
</build></pre>
当启用addResources配置时,任意src/main/resources文件夹在应用运行时将被添加到应用的类路径,同时任意target/class中发现重复的资源将被移除。这将在发布web应用时使资源及时刷新非常有用。例如,当使用HTML,CSS和JavaScript文件时,不用重新编译应用就可以立马看到变化。这对前端开发人员不用下载安装Java IDE就可以工作也是一种非常有用的方式。
需要注意的是,该特性的副作用是在构建时资源过滤不起作用
为了与repackage目标保持一致,run目标在构件类路径下文件时将排除在配置依赖时排除的依赖配置。更详细的的请参考 排除一个依赖 章节。
有时候在运行应用时包含测试依赖也是非常有用的。例如,在测试模式下使用根目录类运行应用。如果希望这样做,可以设置useTestClasspath参数的值为true。注意:尽在运行应用时生效:重新打包目标将不会增加测试依赖到结果jar和war包中。
3.3 使用集成测试
虽然可以很容易从测试(测试套件)本身启动Spring Boot程序,但可能需要在构建自身来处理。为了确信围绕集成测试的Spring Boot应用的生命周期被合适的管理,可以使用start和stop目标。如下配置:
<pre style="font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none; padding: 9.5px; color: rgb(51, 51, 51); border-top-left-radius: 4px; border-top-right-radius: 4px; border-bottom-right-radius: 4px; border-bottom-left-radius: 4px; margin-top: 0px; margin-bottom: 10px; line-height: 20px; word-break: break-all; word-wrap: break-word; white-space: pre-wrap; background-color: rgb(245, 245, 245); border: 1px solid rgba(0, 0, 0, 0.14902);"><build>
...
<plugins>
...
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>1.3.0.BUILD-SNAPSHOT</version>
<executions>
<execution>
<id>pre-integration-test</id>
<goals>
<goal>start</goal>
</goals>
</execution>
<execution>
<id>post-integration-test</id>
<goals>
<goal>stop</goal>
</goals>
</execution>
</executions>
</plugin>
...
</plugins>
...
</build></pre>
这样的设置现在可以使用failsafe-plugin来运行你的集成测试,正如你所期待的哪样。
更多详细细节,参 考随机端口的集成测试的。
第二部分
第四章 自定义分类重打包
默认情况下,repackage目标将使用可执行的构件来替代原始的构件。如果希望保留原是构件,并且也使用不同的分类来附属保留可执行的构件,可以配置如下:
说明:如果不适用repackage目标,那么maven执行package命令生成的jar包只有一个,名称为pom.xml里面配置的name(artifactId)-version.jar
如果加入了repackage配置,则maven打包生成的jar包会被重命名为name-version.jar.original,使用repackage重新打包生成的jar包名称为name-version.jar,
下面的配置就是如果希望保留原始构件生成的jar包名称不变,同时也想保留repackage打包生成的jar包,可以自定义命名。
<pre style="font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none; padding: 9.5px; color: rgb(51, 51, 51); border-top-left-radius: 4px; border-top-right-radius: 4px; border-bottom-right-radius: 4px; border-bottom-left-radius: 4px; margin-top: 0px; margin-bottom: 10px; line-height: 20px; word-break: break-all; word-wrap: break-word; white-space: pre-wrap; background-color: rgb(245, 245, 245); border: 1px solid rgba(0, 0, 0, 0.14902);"><project>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>1.3.0.BUILD-SNAPSHOT</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
<configuration>
<classifier>exec</classifier>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project></pre>
如上配置,那么使用repackage重新生成的包的名称就是name-version-exec.jar,就是在version后面追加了configuration节点中的classifier节点中的值,该值是自定义的。但是如果classifier节点中什么值都不写,那么就和默认的repackage配置一样,即原始的构件为name-version.jar.original,repackage打包的jar为name-version.jar
第五章 排除依赖
默认情况下,repackage和run目标都会包含所有provided scope的依赖。基于boot的项目应该考虑provided scope的依赖就像容器所需要的依赖包来使应用可以运行。
有三种方式可以排除运行时被打包使用的依赖
1、通过指定groupId和artifactId来排除依赖(如果需要可以指定classifier,这是可选的)
2、通过指定artifactId,来排除所有匹配的依赖
3、通过指定groupId,来排除所有属于该group的依赖
如下通过指定groupId和artifactId排除依赖
<pre style="font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none; padding: 9.5px; color: rgb(51, 51, 51); border-top-left-radius: 4px; border-top-right-radius: 4px; border-bottom-right-radius: 4px; border-bottom-left-radius: 4px; margin-top: 0px; margin-bottom: 10px; line-height: 20px; word-break: break-all; word-wrap: break-word; white-space: pre-wrap; background-color: rgb(245, 245, 245); border: 1px solid rgba(0, 0, 0, 0.14902);"><project>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>1.3.0.BUILD-SNAPSHOT</version>
<configuration>
<excludes>
<exclude>
<groupId>com.foo</groupId>
<artifactId>bar</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project></pre>
如上配置就会排除对com.foo:bar的jar包
如下通过指定artifactId,来排除artifactId与此匹配的所有依赖
<pre style="font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none; padding: 9.5px; color: rgb(51, 51, 51); border-top-left-radius: 4px; border-top-right-radius: 4px; border-bottom-right-radius: 4px; border-bottom-left-radius: 4px; margin-top: 0px; margin-bottom: 10px; line-height: 20px; word-break: break-all; word-wrap: break-word; white-space: pre-wrap; background-color: rgb(245, 245, 245); border: 1px solid rgba(0, 0, 0, 0.14902);"><project>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>1.3.0.BUILD-SNAPSHOT</version>
<configuration>
<excludeArtifactIds>my-lib,another-lib</excludeArtifactIds>
</configuration>
</plugin>
</plugins>
</build>
</project></pre>
如上配置就会排除所有artifactId为my-lib和another-lib的jar包
如下通过指定groupId,来排除groupId与此匹配的所有依赖
<pre style="font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none; padding: 9.5px; color: rgb(51, 51, 51); border-top-left-radius: 4px; border-top-right-radius: 4px; border-bottom-right-radius: 4px; border-bottom-left-radius: 4px; margin-top: 0px; margin-bottom: 10px; line-height: 20px; word-break: break-all; word-wrap: break-word; white-space: pre-wrap; background-color: rgb(245, 245, 245); border: 1px solid rgba(0, 0, 0, 0.14902);"><project>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>1.3.0.BUILD-SNAPSHOT</version>
<configuration>
<excludeGroupIds>com.foo</excludeGroupIds>
</configuration>
</plugin>
</plugins>
</build>
</project></pre>
如上配置则排除掉所有groupId为com.foo的jar包
第六章 调试应用
默认情况下,run目标和mvn命令是在同一个进程中执行的,除非jvm参数或者客户端明确指定。可以通过使用fork属性明确的开启或者关闭是否在同一进程中执行。
如果需要fork这个进程并且进行调试,可以添加需要的JVM参数来开启远程调试。如下配置为挂起进程,直到有调试请求从5005端口进入。
<pre style="font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none; padding: 9.5px; color: rgb(51, 51, 51); border-top-left-radius: 4px; border-top-right-radius: 4px; border-bottom-right-radius: 4px; border-bottom-left-radius: 4px; margin-top: 0px; margin-bottom: 10px; line-height: 20px; word-break: break-all; word-wrap: break-word; white-space: pre-wrap; background-color: rgb(245, 245, 245); border: 1px solid rgba(0, 0, 0, 0.14902);"><project>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>1.3.0.BUILD-SNAPSHOT</version>
<configuration>
<jvmArguments>
-Xdebug -Xrunjdwp:transport=dt_sorket,server=y,suspend=y,address=5005
</jvmArguments>
</configuration>
</plugin>
</plugins>
</build>
</project></pre>
需要注意的是,只要你指定了这些JVM参数,这个进程就会自动被fork。这些jvm擦书也可以在命令行中指定,确认书写正确:
<pre style="font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none; padding: 9.5px; color: rgb(51, 51, 51); border-top-left-radius: 4px; border-top-right-radius: 4px; border-bottom-right-radius: 4px; border-bottom-left-radius: 4px; margin-top: 0px; margin-bottom: 10px; line-height: 20px; word-break: break-all; word-wrap: break-word; white-space: pre-wrap; background-color: rgb(245, 245, 245); border: 1px solid rgba(0, 0, 0, 0.14902);">mvn spring-boot:run -Drun.jvmArguments="-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5005"</pre>
第七章 集成测试的随机端口
Spring Boot集成测试的一个好特性是它能够为Web应用分配一个空闲端口。当start目标插件使用时,Spring Boot应用是被分离执行的,这让传递给集成测试程序本身实际的端口变得非常困难。
如下的配置展示如何使用build-help-plugin插件达到相同的特性。
<pre style="font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none; padding: 9.5px; color: rgb(51, 51, 51); border-top-left-radius: 4px; border-top-right-radius: 4px; border-bottom-right-radius: 4px; border-bottom-left-radius: 4px; margin-top: 0px; margin-bottom: 10px; line-height: 20px; word-break: break-all; word-wrap: break-word; white-space: pre-wrap; background-color: rgb(245, 245, 245); border: 1px solid rgba(0, 0, 0, 0.14902);"><project>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<executions>
<execution>
<id>reserve-tomcat-port</id>
<goals>
<goal>reserve-network-port</goal>
</goals>
<phase>process-resources</phase>
<configuration>
<portNames>
<portName>tomcat.http.port</portName>
</portNames>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>1.3.0.BUILD-SNAPSHOT</version>
<executions>
<execution>
<id>pre-integration-test</id>
<goals>
<goal>start</goal>
</goals>
<configuration>
<arguments>
<argument>--server.port={tomcat.http.port}</test.server.port>
</systemPropertyVariables>
</configuration>
</plugin>
</plugins>
</build></pre>
现在可以在任意的集成测试中查询test.server.port系统属性来给server创建一个合适的url。
第八章 指定使用的配置文件
一个特定应用使用的配置文件可以通过profiles参数指定。如下配置启动了foo和bar两个配置文件:
<pre style="font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none; padding: 9.5px; color: rgb(51, 51, 51); border-top-left-radius: 4px; border-top-right-radius: 4px; border-bottom-right-radius: 4px; border-bottom-left-radius: 4px; margin-top: 0px; margin-bottom: 10px; line-height: 20px; word-break: break-all; word-wrap: break-word; white-space: pre-wrap; background-color: rgb(245, 245, 245); border: 1px solid rgba(0, 0, 0, 0.14902);"><project>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>1.3.0.BUILD-SNAPSHOT</version>
<configuration>
<profiles>
<profile>foo</profile>
<profile>bar</profile>
</profiles>
</configuration>
</plugin>
</plugins>
</build>
</project></pre>
使用哪个配置文件也可以通过命令行参数配置,如果有多个,需要使用都好将他们隔开:
mvn spring-boot:run -Drun.profiles=bar,foo
推荐阅读
-
spring boot整合Shiro实现单点登录的示例代码
-
spring boot实现验证码功能
-
spring boot 与kafka集成的示例代码
-
spring boot Logging的配置以及使用详解
-
Spring Boot启动及退出加载项的方法
-
spring boot利用docker构建gradle项目的实现步骤
-
Spring Boot+Mybatis+Druid+PageHelper实现多数据源并分页的方法
-
Spring Boot整合ElasticSearch实现多版本兼容的方法详解
-
详解手把手Maven搭建SpringMVC+Spring+MyBatis框架(超级详细版)
-
Spring Boot实战之模板引擎