내가 어떻게 프로그램 종료 봄 부팅 응용 프로그램 VM을 종료하지 않고 ?
다른 작품에서 반대되는 것은 무엇입니까?
new SpringApplication(Main.class).run(args);
내가 어떻게 프로그램 종료 봄 부팅 응용 프로그램 VM을 종료하지 않고 ?
다른 작품에서 반대되는 것은 무엇입니까?
new SpringApplication(Main.class).run(args);
답변:
닫기는 SpringApplication
기본적으로 기본 ApplicationContext
. SpringApplication#run(String...)
방법은 당신이주는 ApplicationContext
A와를 ConfigurableApplicationContext
. 그런 다음 close()
직접 할 수 있습니다 .
예를 들면
@SpringBootApplication
public class Example {
public static void main(String[] args) {
ConfigurableApplicationContext ctx = SpringApplication.run(Example.class, args);
// ...determine it's time to shut down...
ctx.close();
}
}
또는 static
SpringApplication.exit(ApplicationContext, ExitCodeGenerator...)
도우미 메서드를 사용하여 수행 할 수 있습니다. 예를 들면
@SpringBootApplication
public class Example {
public static void main(String[] args) {
ConfigurableApplicationContext ctx = SpringApplication.run(Example.class, args);
// ...determine it's time to stop...
int exitCode = SpringApplication.exit(ctx, new ExitCodeGenerator() {
@Override
public int getExitCode() {
// no errors
return 0;
}
});
// or shortened to
// int exitCode = SpringApplication.exit(ctx, () -> 0);
System.exit(exitCode);
}
}
ExitCodeGenerator
은이 사용 방법을 보여줍니다 . main
메서드 에서 돌아와서 정상적으로 종료 할 수 있습니다 (종료 코드 0).
스프링 부트 애플리케이션에서 다음과 같이 사용할 수 있습니다.
ShutdownManager.java
import org.springframework.context.ApplicationContext;
import org.springframework.boot.SpringApplication;
@Component
class ShutdownManager{
@Autowired
private ApplicationContext appContext;
public void initiateShutdown(int returnCode){
SpringApplication.exit(appContext, () -> returnCode);
}
}
ApplicationContext
을 다른 빈에 자동으로 주입 할 수 있음 을 보여주기 위해 찬성합니다 .
이것은 작동합니다.
SpringApplication.run(MyApplication.class, args).close();
System.out.println("done");
추가 그래서 .close()
후run()
설명:
public ConfigurableApplicationContext run(String... args)
Spring 애플리케이션을 실행하여 새 ApplicationContext를 만들고 새로 고칩니다. 매개 변수 :
args
-응용 프로그램 인수 (일반적으로 Java 기본 메서드에서 전달됨)반환 값 : 실행중인 ApplicationContext
과:
void close()
이 애플리케이션 컨텍스트를 닫고 구현이 보유 할 수있는 모든 자원 및 잠금을 해제하십시오. 여기에는 캐시 된 모든 싱글 톤 Bean 삭제가 포함됩니다. 참고 : 상위 컨텍스트에서 닫기를 호출하지 않습니다. 상위 컨텍스트에는 고유 한 독립적 인 수명주기가 있습니다.이 메서드는 부작용없이 여러 번 호출 될 수 있습니다. 이미 닫힌 컨텍스트에 대한 후속 닫기 호출은 무시됩니다.
따라서 기본적으로 부모 컨텍스트를 닫지 않으므로 VM이 종료되지 않습니다.
SpringApplication.exit(appContext, () -> returnCode)
.
SpringApplication.run(MyApplication.class, args)
부모 컨텍스트가 없습니다. 하나의 컨텍스트 생성에 의해 반환 된 컨텍스트있어 run
다음 바로는 close
. @Michael이 맞습니다. 이것은 대부분의 프로그램 인 Spring 컨텍스트가 초기화 된 후에 아무것도해야하는 프로그램에서는 작동하지 않습니다.
응용 프로그램에서 당신은 사용할 수 있습니다 SpringApplication
. 여기에는 exit()
두 개의 인수를 받는 정적 메서드가 있습니다 : the ApplicationContext
및 an ExitCodeGenerator
:
즉,이 메서드를 선언 할 수 있습니다.
@Autowired
public void shutDown(ExecutorServiceExitCodeGenerator exitCodeGenerator) {
SpringApplication.exit(applicationContext, exitCodeGenerator);
}
통합 테스트 내@DirtiesContext
에서 클래스 수준에서 주석을 추가하여이를 달성 할 수 있습니다 .
@DirtiesContext(classMode=ClassMode.AFTER_CLASS)
-연결된 ApplicationContext는 테스트 클래스 이후에 더티로 표시됩니다.@DirtiesContext(classMode=ClassMode.AFTER_EACH_TEST_METHOD)
-연결된 ApplicationContext는 클래스의 각 테스트 메서드 후에 더티로 표시됩니다.즉
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = {Application.class},
webEnvironment= SpringBootTest.WebEnvironment.DEFINED_PORT, properties = {"server.port:0"})
@DirtiesContext(classMode= DirtiesContext.ClassMode.AFTER_CLASS)
public class ApplicationIT {
...
이렇게하면 SpringBoot 애플리케이션이 제대로 닫히고 리소스가 운영 체제로 다시 해제됩니다.
@Autowired
private ApplicationContext context;
@GetMapping("/shutdown-app")
public void shutdownApp() {
int exitCode = SpringApplication.exit(context, (ExitCodeGenerator) () -> 0);
System.exit(exitCode);
}