如何中止Spring-Boot启动?

时间:2016-12-02 20:55:12

标签: java spring-boot watchservice

我正在编写一个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启动。有人知道我怎么做吗?

3 个答案:

答案 0 :(得分:3)

获取应用程序上下文,例如:

@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。

答案 1 :(得分:1)

可接受的答案是正确的,但不必要地复杂。不需要Condition,然后检查bean是否存在,然后关闭ApplicationContext。在WatchService创建期间仅检查目录是否存在,并引发异常将由于无法创建Bean而中止应用程序启动。

答案 2 :(得分:-2)

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

  

每个SpringApplication都会向JVM注册一个关闭钩子   确保在退出时正常关闭ApplicationContext。所有   标准的Spring生命周期回调(例如DisposableBean)   可以使用interface或@PreDestroy注释。

     

另外,bean可以实现   org.springframework.boot.ExitCodeGenerator接口,如果他们愿意   在应用程序结束时返回特定的退出代码。

您应该实现释放资源/文件的@PreDestroy方法。然后在启动期间,当您检测到某些错误时,您可以抛出一些def index(request): allAlbums = Album.objects.all() html = '' for album in allAlbums: url = '/music/' + str(album.id) + '/' html += '<a href ="' + url + '">' + album.albumTitle + '</a><br>' return HttpResponse(html) - 它会开始关闭应用程序上下文。