San*_*eep 6 java tomcat gradle maven spring-boot
如此快速的澄清是因为我已经阅读了之前的一些类似问题:
我已经看过https://www.toptal.com/spring-boot/spring-boot-application-programmatic-launch。它非常有帮助,但我不确定如何编译和加载 Spring Boot 应用程序。
我有一种暗示,这是在 Tomcat TomcatServletWebServerFactory 级别完成的 - 基本上 Spring Boot“helper”应用程序将触发 tomcat 加载外部 jar 并部署。我不能 100% 确定这是否正确。
\xe2\x80\x99 是否可以简单地在从主 Spring Boot 应用程序中启动的外部进程中构建并运行辅助 Spring Boot 应用程序?
\n我\xe2\x80\x99ve刚刚在一个非常简单的概念验证中尝试了这个。对于此 POC,我创建了两个虚拟 Spring Boot 应用程序,一个名为outer
,另一个名为inner
. 后者应该由前者建造和运营。
这里\xe2\x80\x99s 是目录结构(为了简洁起见,在两个 Gradle 项目中省略了Gradle 7.6 Wrapper文件):
\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 inner\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 build.gradle\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 settings.gradle\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 src\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 main\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 java\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 com\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 example\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 demo\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 DemoApplication.java\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 resources\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 application.properties\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 outer\n \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 build.gradle\n \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 settings.gradle\n \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 src\n \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 main\n \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 java\n \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 com\n \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 example\n \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 demo\n \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 DemoApplication.java\n
Run Code Online (Sandbox Code Playgroud)\n这两个settings.gradle
文件都是空的。这两个build.gradle
文件也具有相同的内容:
plugins {\n id \'java\'\n id \'org.springframework.boot\' version \'2.7.6\'\n id \'io.spring.dependency-management\' version \'1.1.0\'\n}\n\nrepositories {\n mavenCentral()\n}\n\ndependencies {\n implementation \'org.springframework.boot:spring-boot-starter-web\'\n}\n
Run Code Online (Sandbox Code Playgroud)\n\xe2\x80\x9cinner\xe2\x80\x9d 应用程序是Spring 快速入门指南中的演示应用程序,即inner/src/main/java/com/example/demo/DemoApplication.java
如下所示:
package com.example.demo;\n\nimport org.springframework.boot.SpringApplication;\nimport org.springframework.boot.autoconfigure.SpringBootApplication;\nimport org.springframework.web.bind.annotation.GetMapping;\nimport org.springframework.web.bind.annotation.RequestParam;\nimport org.springframework.web.bind.annotation.RestController;\n\n@SpringBootApplication\n@RestController\npublic class DemoApplication {\n\n public static void main(String[] args) {\n SpringApplication.run(DemoApplication.class, args);\n }\n\n @GetMapping("/hello")\n public String hello(@RequestParam(value = "name", defaultValue = "World") String name) {\n return String.format("Hello %s!", name);\n }\n}\n
Run Code Online (Sandbox Code Playgroud)\n该inner/src/main/resources/application.properties
文件还包含以下内容server.port=8081
,以便其 Web 服务器在与 \xe2\x80\x9couter\xe2\x80\x9d 端口不同的端口上运行。
这让我们outer/src/main/java/com/example/demo/DemoApplication.java
定义了以下(原始)应用程序:
package com.example.demo;\n\nimport org.springframework.boot.SpringApplication;\nimport org.springframework.boot.autoconfigure.SpringBootApplication;\nimport org.springframework.web.bind.annotation.PostMapping;\nimport org.springframework.web.bind.annotation.RestController;\n\nimport java.io.File;\nimport java.io.IOException;\n\n@SpringBootApplication\n@RestController\npublic class DemoApplication {\n\n private Process otherAppProcess = null;\n\n public static void main(String[] args) {\n SpringApplication.run(DemoApplication.class, args);\n }\n\n @PostMapping("/run")\n public String run() throws IOException, InterruptedException {\n synchronized (this) {\n if (otherAppProcess != null) {\n stop();\n }\n var processBuilder = new ProcessBuilder("./gradlew", "bootRun");\n processBuilder.directory(new File("../inner"));\n otherAppProcess = processBuilder.start();\n }\n return "Done.";\n }\n\n @PostMapping("/stop")\n public String stop() {\n synchronized (this) {\n if (otherAppProcess != null) {\n otherAppProcess.destroy();\n otherAppProcess = null;\n }\n }\n return "Ok.";\n }\n}\n
Run Code Online (Sandbox Code Playgroud)\n您现在可以运行./gradlew bootRun
\ outer/
xe2\x80\x9couter\xe2\x80\x9d Spring Boot应用程序\xe2\x80\x93来启动Tomcat Web服务器。该服务器响应 POST 请求,启动 \xe2\x80\x9cinner\xe2\x80\x9d Spring Boot 应用程序的 Gradle 构建,该应用程序也运行该应用程序(构建完成后)。例如,您现在可以尝试以下交互:
$ curl -X GET http://localhost:8081/hello\ncurl: (7) Failed to connect to localhost port 8081 after 0 ms: Connection refused\n$ curl -X POST http://localhost:8080/run\nDone.\n$ curl -X GET http://localhost:8081/hello\nHello World!\n$ curl -X POST http://localhost:8080/stop\nOk.\n
Run Code Online (Sandbox Code Playgroud)\n
嗯 - 我知道你想要示例代码,但我目前没有时间亲自尝试,这可能不是真正的答案 - 但对于评论来说太大了:
我以前从未做过这样的事情,但也许我可以把我的想法放在这里 - 如果它很糟糕,请随意忽略它。
我不知道您的“主 Spring Boot 项目”是否使用 Maven 包装器,但让我们假设它确实如此。
那么让我们尝试以下概念:
git clone
在其选择的某些目录中从 GitHub / GitLab 中检出 X 个不同的 Spring Boot 应用程序(带有 )。(你可以使用 JGit 或Runtime.getRuntime().exec("your git command") 或任何你想到的东西来做到这一点)gradlew bootJar
)java -jar path/to/your/mySpringBoot.jar fully.qualified.package.Application
从概念上讲,这听起来是不是你想做的?最后,如果我们考虑一下 - 当您手动签出您的项目、构建 JAR 并启动它时,这是一样的 - 不是吗?
归档时间: |
|
查看次数: |
1312 次 |
最近记录: |