【问题标题】:Hot swapping in Spring BootSpring Boot 中的热插拔
【发布时间】:2014-02-19 09:31:36
【问题描述】:

我一直在用 Spring Boot 做 P.O.C。

到目前为止,它的进展非常好,很有希望,但有一个主要缺点:我使用的是嵌入式服务器(即,将 Web 应用程序打包在 .jar 中),所以在开发时我必须重建 jar 和每次更改 CSS、HTML 或 JS 文件时重新启动服务器。没有热插拔。这确实减慢了 UI 开发。

我可以想到几个快速修复,例如从不同的域加载静态资源并从本地 nginx 提供它,还有一些类似的变体,但没有某种内置选项使用 IntelliJ/Eclipse 时?

【问题讨论】:

  • 如果你不介意从 Spring Boot 切换,你可以试试 mason github.com/metamug/mason 它的构建速度很快,可以根据变化重新部署。

标签: java eclipse spring intellij-idea spring-boot


【解决方案1】:

有多种选择。在 IDE 中运行(尤其是在调试时)是一种很好的开发方式(所有现代 IDE 都允许重新加载静态资源,并且通常还允许热交换 Java 类更改)。 Spring Boot devtools 是一种获得相当大提升的廉价方法(只需将其添加到您的类路径中)。当检测到更改时,它通过在热 JVM 中重新启动您的应用程序来工作。它还会在运行时关闭 thymeleaf 缓存之类的东西,因此您不必记住自己这样做。如果您使用更高级别的工具编写该代码,则可以将其与外部 css/js 编译器进程一起使用。

Spring Loaded 不再推荐,但可能仍在使用中。如果您需要零延迟的热交换(例如 JRebel),更复杂的基于代理的工具会更好地工作。

查看docs 了解一些最新内容

【讨论】:

  • 谢谢 dave 我会看看 spring-loaded 和 maven 重新加载静态文件的选项,一个问题:我正在运行 idea12,但我找不到重新打包静态资源的方法在注释驱动配置中运行嵌入式 tomcat 时,您确定它应该可以工作吗?
  • 我不是 IDEA 的普通用户,但我不知道有任何问题。去年我参与了一个项目,每个人都使用它并且从未遇到任何问题。这一定是可能的。也许您必须将 src/main/resources 显式添加到您的类路径中?
  • 我在 IntelliJ 中也遇到了问题。我遵循 Spring Boot 参考并确保 Thymeleaf 的缓存设置设置为 false,但是每当我更改位于 src/main/resources 下的模板时,我都必须重新启动运行嵌入式容器的应用程序
  • 我没有意识到我可以通过在调试模式下启动 STS 来热重载 .class 文件。谢谢!
  • @RoyKachouh Dave 是正确的。请参阅我的答案以获取说明(这真的很简单!)
【解决方案2】:

您也可以使用 JRebel - 它会重新加载所有更改(更好的热插拔),包括 spring bean。它很容易与 Intellij 和 Eclipse 集成。

【讨论】:

    【解决方案3】:

    假设你正在使用 gradle;在 build.gradle 中使用以下配置

    apply plugin: 'java'
    apply plugin: 'idea'
    apply plugin: 'spring-boot'
    apply plugin: 'application'
    
    applicationDefaultJvmArgs = ["-agentlib:jdwp=transport=dt_socket,address=localhost:7000,server=y,suspend=n"]
    
    mainClassName = "package.ApplicationRunner"
    

    使用命令gradle build run从IDE或命令行运行应用程序

    现在 IDE 可以连接到运行 Spring Boot 应用程序的远程 JVM(在端口 7000 上)。还支持静态文件的热部署。

    如果在 IDE 中正确管理依赖项,您甚至可以从 intelliJ 运行主类。主类是包含将调用SpringApplication.run("classpath:/applicationContext.xml", args);的主方法的类

    【讨论】:

      【解决方案4】:

      我推荐Thymeleaf(模板引擎),jRebel for personal developer。 Thymeleaf 模板文件只是 HTML 资源。因此,它们会在您编辑模板文件后立即更改。

      【讨论】:

        【解决方案5】:

        您可以进行热插拔:

        • 对于java代码:使用spring-loaded
        • 对于 Thymeleaf 模板:禁用缓存

        查看此帖子以查看更多详细信息:http://blog.netgloo.com/2014/05/21/hot-swapping-in-spring-boot-with-eclipse-sts/

        【讨论】:

          【解决方案6】:

          在 Intellij 中,我可以得到这种行为。当程序在调试模式下运行时,选择Run > Reload Changed Classes

          注意:Intellij 完成操作后,可能会显示Loaded classes are up to date. Nothing to reload。这是一种误导,因为它实际上确实重新加载了您的类路径资源。

          我的环境/设置包括:
          Intellij 13
          嵌入式 Tomcat
          “应用程序”类型的运行/调试配置(仅使用主类)
          提供静态 html、css 和 js(无 jsp)

          【讨论】:

            【解决方案7】:

            从 1.3.0 开始。 (现在在里程碑 2 中),您可以使用 spring-boot-devtools 作为一种轻量级方法 - 请参阅 docsthis blogpost。 只需升级到 >= 1.3.0。并将以下内容添加到您的 pom.xml:

            <dependencies>
              <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-devtools</artifactId>
              </dependency>
            </dependencies>
            

            比使用 Run As 启动您的 SpringBootApplication... 你很好。

            【讨论】:

              【解决方案8】:

              如果您使用的是 maven,则 pom.xml 中的 spring-boot-maven-plugin 需要像这样才能获得热插拔:

                <plugin>
                      <groupId>org.springframework.boot</groupId>
                      <artifactId>spring-boot-maven-plugin</artifactId>
                      <dependencies>
                          <dependency>
                              <groupId>org.springframework</groupId>
                              <artifactId>springloaded</artifactId>
                              <version>1.2.0.RELEASE</version>
                          </dependency>
                      </dependencies>
                  </plugin>
              

              如果您使用的是 thymeleaf,请将其添加到您的应用程序属性中:

              spring.thymeleaf.cache=false
              

              但请记住:不要在生产环境中使用它..

              【讨论】:

                【解决方案9】:

                我不知道这种支持能走多远,但如果您使用 Eclipse IDE(或任何阅读本文的人):在调试模式下通过 m2e 启动 Spring-Boot 应用程序(按“调试”-下拉按钮并选择您的 Maven 运行配置项)。

                它对我来说就像一个魅力。

                我的maven run配置项配置如下:

                • 目标设置为“spring-boot:run”
                • 基础目录为工程目录

                没有使用任何其他库(甚至没有 spring-boot-devtools)。

                就是这样。

                【讨论】:

                【解决方案10】:

                但是在使用 IntelliJ/Eclipse 时是否没有某种内置选项?

                在 IntelliJ 15.0、Windows 10 中帮助我的是以下序列:

                第 1 步: 在 pom 中添加了以下依赖项(到处都提到了,但仅此一项就可以解决),正如 @jonashackt 所提到的

                <dependency>
                     <groupId>org.springframework.boot</groupId>
                     <artifactId>spring-boot-devtools</artifactId>
                </dependency>
                

                第 2 步: 然后从 File->Settings-> Build-Execution-Deployment -> Compiler(确保选择了主编译器选项而不是它的任何子选项)

                启用自动制作项目。单击确定并关闭对话框 注意:在最新版本中,它将是自动构建项目

                步骤 3: 按住 Shift+Ctrl+A(在 Windows 上)您将看到一个搜索对话框标题为“输入操作或选项名称”,键入注册表。双击显示“注册表...”的第一个选项,它将打开另一个窗口。寻找以下选项:

                compiler.automake.allow.when.app.running
                

                并启用它,点击关闭

                第 4 步:重启 IDE

                由此source详细阐述

                【讨论】:

                • 这只是在保存文件时重启 SpringBoot 还是?
                • 不,它没有,它可以让您在保存时反映更改。
                • 是的,但是当我保存它时,会从头开始重新启动 SpringBoot。我只是想将更改为加载的类。
                【解决方案11】:

                尝试在 pom.xml 中使用这个 spring-boot-devtools 标签

                 <dependencies>
                        <dependency>
                            <groupId>org.springframework.boot</groupId>
                            <artifactId>spring-boot-devtools</artifactId>
                            <optional>true</optional>
                        </dependency>
                 </dependencies>
                

                http://mytechnologythought.blogspot.com/2017/07/how-to-run-server-of-spring-boot-auto.html

                【讨论】:

                • 为什么是optional=true
                • @nabster 当无法(无论出于何种原因)将项目拆分为子模块时,使用可选依赖项。这个想法是,某些依赖项仅用于项目中的某些功能,如果不使用该功能,则不需要。理想情况下,这样的功能将被拆分为依赖于核心功能项目的子模块......阅读更多:maven.apache.org/guides/introduction/…
                【解决方案12】:

                如何在 Springboot 应用中进行热插拔

                1. 使用 gradle 时,在依赖项中包含以下内容: compile group: 'org.springframework.boot', name: 'spring-boot-devtools', version: '2.0.1.RELEASE' & providedRuntime('org.springframework.boot:spring-boot-starter-tomcat')

                2. application.properties 中添加属性 spring.devtools.restart.additional-paths=.

                3. 构建 Gradle,然后将应用程序作为 bootRun 运行

                应用程序已准备好在修改类时执行热交换

                【讨论】:

                  猜你喜欢
                  • 2016-05-14
                  • 2017-03-27
                  • 2018-10-07
                  • 2016-03-25
                  • 2017-02-24
                  • 2020-05-24
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多