[SPRING] 프로그래밍 방식으로 스프링 부트 응용 프로그램 다시 시작 / 스프링 컨텍스트 새로 고침
SPRING프로그래밍 방식으로 스프링 부트 응용 프로그램 다시 시작 / 스프링 컨텍스트 새로 고침
사용자가 개입하지 않아도 Spring Application을 프로그래밍 방식으로 다시 시작하려고합니다.
기본적으로 응용 프로그램의 모드를 전환 할 수있는 페이지가 있습니다. 실제로는 현재 활성 프로필을 전환하는 것을 의미합니다. 그리고 문맥을 다시 시작해야한다는 것을 이해합니다.
현재 내 코드는 매우 간단합니다. 다시 시작하는 비트 용입니다 (이 방법은 Kotlin입니다).
context.close()
application.setEnvironment(context.environment)
ClassUtils.overrideThreadContextClassLoader(application.javaClass.classLoader)
context = application.run(*argsArray)
그러나 context.close ()를 수행하는 순간 JVM이 즉시 존재합니다. 나는 또한 context.refresh ()를 시도했으나 Tomcat / Jetty (단순히 Tomcat 문제 일 때를 모두 시도)를 죽이는 것처럼 보였다. 그런 다음 아무 일도 일어나지 않는다.
나는 또한 프로그램 적으로 봄 부팅 응용 프로그램을 다시 시작한 것으로 보았지만 아무 것도 그 대답에서 나를 위해 작동하는 것 같습니다. 게다가 스프링 엑츄에이터를 살펴 보았습니다. 스프링 액추에이터는 / restart 끝 점이 있지만 더 이상 존재하지 않는 것 같습니까?
도움말 크게 감사하겠습니다. 감사.
해결법
-
==============================
1.Alex의 솔루션이 효과가 있다고하더라도, 나는 하나의 작업을 수행 할 수 있도록 2 가지 추가 종속성 (액추에이터 및 클라우드 컨텍스트)을 포함하는 것을 믿지 않습니다. 대신, 나는 그의 대답을 결합하고 내 코드를 수정하여 내가 원하는 것을 해냈다.
Alex의 솔루션이 효과가 있다고하더라도, 나는 하나의 작업을 수행 할 수 있도록 2 가지 추가 종속성 (액추에이터 및 클라우드 컨텍스트)을 포함하는 것을 믿지 않습니다. 대신, 나는 그의 대답을 결합하고 내 코드를 수정하여 내가 원하는 것을 해냈다.
먼저, 새로운 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)은 필수는 아니지만 응용 프로그램을 실제로 다시 시작하기 전에 내 컨트롤러에서보기를 출력하길 원합니다.
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) }
컨텍스트와 응용 프로그램이 응용 프로그램을 시작할 때 기본 방법에서 오는 경우 :
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) }
이것이 문제를 일으키는 지 확실하지 않습니다. 있을 경우이 대답을 업데이트 할 것입니다. 희망적으로 이것은 다른 사람들에게 도움이 될 것입니다.
-
==============================
2.누군가를 도울 수있는 경우 Crembo의 대답에 대한 Java 번역이 있습니다.
누군가를 도울 수있는 경우 Crembo의 대답에 대한 Java 번역이 있습니다.
컨트롤러 방법 :
@GetMapping("/restart") void restart() { Thread restartThread = new Thread(() -> { try { Thread.sleep(1000); Main.restart(); } catch (InterruptedException ignored) { } }); restartThread.setDaemon(false); restartThread.start(); }
기본 클래스 (중요 비트 만) :
private static String[] args; private static ConfigurableApplicationContext context; public static void main(String[] args) { Main.args = args; Main.context = SpringApplication.run(Main.class, args); } public static void restart() { // close previous context context.close(); // and build new one Main.context = SpringApplication.run(Main.class, args); }
-
==============================
3.RestartEndPoint (스프링 - 클라우드 컨텍스트 종속성)를 사용하여 스프링 부트 응용 프로그램을 프로그래밍 방식으로 다시 시작할 수 있습니다.
RestartEndPoint (스프링 - 클라우드 컨텍스트 종속성)를 사용하여 스프링 부트 응용 프로그램을 프로그래밍 방식으로 다시 시작할 수 있습니다.
@Autowired private RestartEndpoint restartEndpoint; ... Thread restartThread = new Thread(() -> restartEndpoint.restart()); restartThread.setDaemon(false); restartThread.start();
메모리 누수가 발생할 수 있음을 알리기 위해 예외가 발생하더라도 작동합니다.
이 다른 질문에 대해서도 동일한 대답이 제공되었습니다 (다르게 다르게) : 자바 함수를 사용하여 스프링 부팅에서 호출 액츄에이터 / 재시작 엔드 포인트
-
==============================
4.Spring Devtools의 Restarter를 사용하여이 문제를 해결했습니다. 이것을 pom.xml에 추가하십시오 :
Spring Devtools의 Restarter를 사용하여이 문제를 해결했습니다. 이것을 pom.xml에 추가하십시오 :
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> </dependency>
그런 다음 org.springframework.boot.devtools.restart.Restarter를 사용하십시오. 이것을 부르다 :
Restarter.getInstance().restart();
그것은 나를 위해 작동합니다. 희망이 도움이됩니다.
from https://stackoverflow.com/questions/39386168/programatically-restart-spring-boot-application-refresh-spring-context by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] 스프링 부트를 사용하는 동안 스프링 배치 범위 문제 (0) | 2019.01.31 |
---|---|
[SPRING] 런타임시 스프링 <task : scheduled> 객체는 어떻게 표현됩니까? (0) | 2019.01.31 |
[SPRING] 스프링 보안 3.2 특정 URL에 대한 CSRF 비활성화 (0) | 2019.01.31 |
[SPRING] 적절한 드라이버가 발견되지 않았습니다. (0) | 2019.01.31 |
[SPRING] 웹 응용 프로그램에 shutDownHook 등록 (0) | 2019.01.30 |