spring-boot-devtools 重载多模块maven项目变化

spring-boot-devtools reload of multi-module maven project changes

多模块maven项目变更重载


设置

想象一个多模块的 maven 项目。项目结构为:

pom.xml //parentpom
   |
  pom.xml //submodule_1
   |
  pom.xml //submodule_2
   .
   .
   .
  pom.xml //submodule_7

例如 submodule_5 有 submodule_6 和 submodule_7 作为依赖项。可以构建 submodule_5 以构建可以部署的 War 文件。 Spring-Boot-Devtools 提供了每当 submodule_5 它的类路径发生变化时自动重启的功能。

只要应用程序 运行 使用:

mvn spring-boot:run

并对 submodule_5 进行了更改(取决于您使用的 IDE 类路径发生了变化。(对于 Eclipse automaticaly / 对于 IntelliJ 当按下 Ctrl+F9)) spring-boot 自动重启应用程序并添加更改. submodule_6 或 submodule_7 发生的更改不会触发自动重启。


问题

  1. 有没有办法让你在 submodule_6 或 submodule_7 中进行更改时强制重启并应用更改?
  2. Spring-boot-devtools 使用两个类加载器:"The Base Classloader" & "The Restart Classloader"。是否在应用程序初始启动时 submodule_6 和 submodule_7 被添加到 "The Base Classloader" 而 submodle_5 保留在 "The Restart Classloader" 中?这样一来,每当 submodule_5 强制重启时,它都会使用 "The Base Classloader"?
  3. 中的 submodule_6 和 submodule_7 版本

您可以在 application.properties:

中指定 spring-boot-devtools 监视的其他文件夹
spring.devtools.restart.additional-paths=../submodule_6,../submodule_7

请参阅 Spring 关于 using-boot-devtools-restart-additional-paths 的文档。

为了解决这个问题,我从 InteliJ 中启动了 运行 应用程序。无需添加。

spring.devtools.restart.additional-paths=../submodule_6,../submodule_7

IntelliJspring-boot 似乎可以很好地协同工作。它首先对我不起作用的原因是因为我一开始是在命令行下工作的。

命令行和IDE

的区别

所以spring-boot-devtools使用两个类加载器来加载应用程序。 Jars 将在 "Base classloader" 中加载 ones,您的应用程序将在 "restart classloader" 中加载。每次类路径发生变化时,最后一个类加载器都会重新启动。

每当从命令行 运行 submodule_5 时,它将构建 submodule_6 和 submodule_7 并将 jars 添加到 submodule_5 的构建中。每当在 submodule_6 和 submodule_7 中进行更改时,spring-boot 甚至不会注意到,因为它只是在监视 submodule_5 并且拥有它需要的罐子。即使你特别告诉它也要监视那些子模块,它仍然不会重建那些,它只会继续使用它已经加载到 "base classloader" 中的 jar(这是我的假设,我不是100% 确定其工作方式)。

每当 运行 submodule_5 来自 IDE 时,它不会创建 submodule_6 和 submodule_7 的 jar。它只会使用它们的类路径。这使得整个项目的类路径(所有子模块)中的更改将触发自动重启并应用更改。

额外

每当 运行 从 IDE 更改为 html-files、css-files、xml-files 等资源时。 . .不会触发重启,因为这不是类路径中的更改。但更改仍然可见。

我尝试了 spring.devtools.restart.additional-paths,无论如何它都没用:更改源重新启动应用程序但无能为力,因为应用程序在执行期间没有 target/classes 模块。

在最近的 IntelliJ 版本上执行 spring-boot:run:开箱即用。

在命令行上执行spring-boot:run:至少有两种情况。

案例 1)我们想从具有 spring boot main class 的模块执行 spring-boot:run(op 问题中的 submodule_5)。 我们需要在其 pom.xml 的插件配置中添加我们希望 spring-boot 插件注意的已编译 classes 的额外 class 路径:

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <configuration>                    
                <folders>
                    <folder>                            
                           ../submodule_6/target/classes
                    </folder>
                    <folder>                            
                           ../submodule_7/target/classes
                    </folder>
                </folders>
            </configuration>
        </plugin>
    </plugins>
</build>

情况 2) 我们想从父模块执行 spring-boot:run
它仅适用于也是模块父级的 pom 多模块。
我们需要做两个改变:
首先,在父 pom 中添加带有标志 skip 的 spring 引导插件声明:

 `<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <version>2.4.1</version>
            <configuration>
                <skip>true</skip>
            </configuration>
        </plugin>

    </plugins>
 </build>`

然后在有spring boot main class的模块的pom.xml中添加(submodule_5 in the op question):

 <build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <configuration>
                <skip>false</skip>                 
            </configuration>
        </plugin>
    </plugins>
</build>

我们现在可以从父 pom 启动应用程序:

mvn -pl submodule_5 -am spring-boot:run

仅供参考,这些 Maven 标志指定在 submodule_5 上应用其依赖项后应用目标(而 multi/parent pom.xml 中的跳过标志)。