我如何中止弹簧靴启动



我正在编写一个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;
    }
}

如果注册目录失败,我想优雅地中止春季启动。有人知道我该怎么做吗?

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

@Autowired
private ConfigurableApplicationContext ctx;

如果找不到目录:

,请调用close方法
ctx.close();

优雅地关闭应用程序上下文,从而使Spring Boot应用程序本身。

更新

基于问题中提供的代码的更详细的示例。

主类

@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();
        }
    }
}

手表服务配置

@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();
    }
}

根据目录是否存在,制作手表服务bean @Conditional。然后在您的主要课程中,检查WatchService Bean是否存在,如果不致电close()

,请关闭应用程序上下文

接受的答案是正确的,但不必要地复杂。不需要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/referene/htmlsingle/htmlsingle/#boot-features-features-application-application-application-exit-exit-exit

每个SpringApplication将在JVM上注册一个关闭挂钩 确保ApplicationContext在退出时优雅地关闭。全部 标准的春季生命周期回调(例如DisposableBean 可以使用界面或@Predestroy注释)。

此外,bean可以实施 org.springframework.boot.exitcodegenerator接口 申请结束时返回特定的出口代码。

您应该实现释放资源/文件的@predestroy方法。然后在启动期间,当您检测到某些错误时,您可以投掷一些RuntimeException - 它开始关闭应用程序上下文。

相关内容

  • 没有找到相关文章

最新更新