簡體   English   中英

如何中止 Spring-Boot 啟動?

[英]How can I abort Spring-Boot startup?

我正在編寫一個 Spring-Boot 應用程序來監視目錄並處理添加到其中的文件。 我在配置類中使用WatchService注冊目錄:

@Configuration
public class WatchServiceConfig {

    private static final Logger logger = LogManager.getLogger(WatchServiceConfig.class);

    @Value("${dirPath}")
    private String dirPath;

    @Bean
    public WatchService register() {
        WatchService watchService = null;

        try {
            watchService = FileSystems.getDefault().newWatchService();
            Paths.get(dirPath).register(watchService, ENTRY_CREATE);
            logger.info("Started watching \"{}\" directory ", dlsDirPath);
        } catch (IOException e) {
            logger.error("Failed to create WatchService for directory \"" + dirPath + "\"", e);
        }

        return watchService;
    }
}

如果注冊目錄失敗,我想優雅地中止 Spring Boot 啟動。 有人知道我該怎么做嗎?

獲取應用程序上下文,例如:

@Autowired
private ConfigurableApplicationContext ctx;

如果找不到目錄,則調用close方法:

ctx.close();

這樣可以優雅地關閉Application Context,從而關閉Spring Boot Application本身。

更新

基於問題中提供的代碼的更詳細示例。

主類

@SpringBootApplication
public class GracefulShutdownApplication {

    public static void main(String[] args) {
        ConfigurableApplicationContext ctx = SpringApplication.run(GracefulShutdownApplication.class, args);
        try{
            ctx.getBean("watchService");
        }catch(NoSuchBeanDefinitionException e){
            System.out.println("No folder to watch...Shutting Down");
            ctx.close();
        }
    }

}

WatchService配置

@Configuration
public class WatchServiceConfig {

    @Value("${dirPath}")
    private String dirPath;

    @Conditional(FolderCondition.class)
    @Bean
    public WatchService watchService() throws IOException {
        WatchService watchService = null;
        watchService = FileSystems.getDefault().newWatchService();
        Paths.get(dirPath).register(watchService, ENTRY_CREATE);
        System.out.println("Started watching directory");
        return watchService;
    }

文件夾條件

public class FolderCondition implements Condition{

    @Override
    public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
        String folderPath = conditionContext.getEnvironment().getProperty("dirPath");
        File folder = new File(folderPath);
        return folder.exists();
    }
}

根據目錄是否存在,使WatchService Bean @Conditional成為可能。 然后在Main Class中,檢查WatchService Bean是否存在,如果不是通過調用close()關閉Application Context。

接受的答案是正確的,但不必要的復雜。 不需要Condition ,然后檢查bean的存在,然后關閉ApplicationContext 只需在WatchService創建期間檢查目錄是否存在,並拋出異常,就會因為無法創建bean而中止應用程序啟動。

如果您對當前IOException的消息傳遞沒問題,您可以讓 bean 拋出它以中止啟動:

@Bean
public WatchService watchService() throws IOException {
    WatchService watchService = FileSystems.getDefault().newWatchService();
    Paths.get(dirPath).register(watchService, ENTRY_CREATE);
    logger.info("Started watching \"{}\" directory ", dlsDirPath);
}

如果您想要比默認IOException更友好的錯誤消息(以更好地幫助用戶指出錯誤),您可以使用自定義異常消息拋出自己的異常:

@Bean
public WatchService watchService() {
    try {
        WatchService watchService = FileSystems.getDefault().newWatchService();
        Paths.get(dirPath).register(watchService, ENTRY_CREATE);
        logger.info("Started watching \"{}\" directory ", dlsDirPath);
        return watchService;
    } catch (IOException e) {
        throw new IllegalStateException(
                "Failed to create WatchService for directory \"" + dirPath + "\"", e);
    }
}

https://docs.spring.io/spring-boot/docs/2.1.1.RELEASE/reference/htmlsingle/#boot-features-application-exit

每個SpringApplication都會向JVM注冊一個關閉鈎子,以確保在退出時正常關閉ApplicationContext。 可以使用所有標准的Spring生命周期回調(例如DisposableBean接口或@PreDestroy注釋)。

此外,如果bean希望在應用程序結束時返回特定的退出代碼,則bean可以實現org.springframework.boot.ExitCodeGenerator接口。

您應該實現釋放資源/文件的@PreDestroy方法。 然后在啟動期間,當您檢測到某些錯誤時,您可能會拋出一些RuntimeException - 它會開始關閉應用程序上下文。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM