java - 以编程方式重启 Spring Boot 应用程序/刷新 Spring Context

标签 java spring spring-mvc spring-boot kotlin

我正在尝试以编程方式重新启动我的 Spring 应用程序,而无需用户干预。

基本上,我有一个页面允许切换应用程序的模式(实际上意味着切换当前 Activity 的配置文件),据我所知,我必须重新启动上下文。

目前我的代码很简单,只是用于重启位(顺便说一下这是 Kotlin):

    context.close()
    application.setEnvironment(context.environment)
    ClassUtils.overrideThreadContextClassLoader(application.javaClass.classLoader)
    context = application.run(*argsArray)

但是,当我执行 context.close() 时,JVM 立即存在。我也尝试过 context.refresh() 但这似乎只是杀死了 Tomcat/Jetty(都尝试过,以防万一它是 Tomcat 问题)然后什么也没有发生。

我也看过Programmatically restart Spring Boot application但这些答案似乎对我没有任何帮助。此外,我查看了应该具有 /restart 端点的 Spring Actuator,但它似乎不再存在?

最佳答案

即使 Alex 的解决方案有效,我也不相信仅仅为了能够包含 2 个额外的依赖项(ActuatorCloud Context)做一项操作。相反,我结合了他的答案并修改了我的代码以做我想做的事。

因此,首先,使用new Thread()setDaemon(false); 执行代码是至关重要的。我有以下处理重启的端点方法:

val restartThread = Thread {
    logger.info("Restarting...")
    Thread.sleep(1000)
    SpringMain.restartToMode(AppMode.valueOf(change.newMode.toUpperCase()))
    logger.info("Restarting... Done.")
}
restartThread.isDaemon = false
restartThread.start()

Thread.sleep(1000) 不是必需的,但我希望我的 Controller 在实际重新启动应用程序之前输出 View 。

SpringMain.restartToMode 有以下内容:

@Synchronized fun restartToMode(mode: AppMode) {
    requireNotNull(context)
    requireNotNull(application)

    // internal logic to potentially produce a new arguments array

    // close previous context
    context.close()

    // and build new one using the new mode
    val builder = SpringApplicationBuilder(SpringMain::class.java)
    application = builder.application()
    context = builder.build().run(*argsArray)
}

其中 contextapplication 在启动应用程序时来自 main 方法:

val args = ArrayList<String>()
lateinit var context: ConfigurableApplicationContext
lateinit var application: SpringApplication

@Throws(Exception::class)
@JvmStatic fun main(args: Array<String>) {
    this.args += args

    val builder = SpringApplicationBuilder(SpringMain::class.java)
    application = builder.application()
    context = builder.build().run(*args)
}

我不完全确定这是否会产生任何问题。如果有,我会更新这个答案。希望这对其他人有任何帮助。

关于java - 以编程方式重启 Spring Boot 应用程序/刷新 Spring Context,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39386168/

相关文章:

java - 删除空格后电子邮件地址中存在非法字符

java - 如何在 Scala 中使用可变参数方法实现 Java 接口(interface)?

带有 OAuth2 丢失 session 的 Spring Security

java - Spring MVC 3.2.3 Tiles 2 HTTP Status 500 - Servlet appServlet 的 Servlet.init() 引发异常

java - 在 SpringMVC 中启用日志记录,而不是使用 Spring-boot

java - 让java显示正确的减量

java - 在android中创建类似glide和picasso的类结构

java - 添加 AOP 建议时 Spring Boot 应用程序上下文被破坏

java - 如何在 Spring 事务中获取连接?

java - 如何使 thymeleaf spring 安全命名空间可用?