3

我有 SpringBoot 应用程序,它加载一些配置并在使用 @PostConstract 注释的方法中运行长时间处理。如果应用程序成功完成或出现错误,则应释放一些资源。

问题是如何最正确地释放应用资源?这是否足以在 @PreDestroy 注释方法中实现,或者我还应该在 @PostConstract 注释方法中捕获异常。

@SpringBootApplication
@Import(MyConfiguration.class)
public class MySpringApplication {

    @Autowire
    ProcessRunner processRunner;

    @Autowire
    ResourceBean resourceBean;

    public static void main(String[] args) {
        SpringApplication.run(MySpringApplication.class, args);
    }

    @PostConstruct
    void postConstruct {
        try {
            processRunner.run()
        } catch (Exception ex) {
            // Do we really need this Exception handling to release resource? 
            resourceBean.release();
        }
    }

    @PreDestroy
    void preDestroy() {
        resourceBean.release();
    }
}
4

2 回答 2

3

PreDestroy 在上下文释放 bean 时用作回调(即:在上下文关闭时)。这意味着 PreDestroy 不与 PostConstruct 耦合。如果 bean 存在于上下文中并被释放,则会调用 predestroy。

PostConstruct 意味着初始化 bean。如果它抛出异常,应用程序将不会启动。

所以,回答你的问题...

如果我们在 postconstract 中遇到异常,是否授予 predestroy-method-call?

PreDestroy 和 PostConstruct 不耦合。这意味着,如果 PostConstruct 遇到异常但以某种方式被管理并且方法成功结束,则 bean 将被初始化并在上下文中可用。当时机成熟且上下文关闭时,bean 将被释放并调用 PreDestroy。

如果 PostConstruct 抛出异常,则 Bean 在上下文中将不可用(并且应用程序不会启动),因此不会调用 PreDestroy。

问题是如何最正确地释放应用资源?这是否足以在 @PreDestroy 注释方法中实现,或者我还应该在 @PostConstract 注释方法中捕获异常?

您应该捕获异常并释放任何非托管资源。这也适用于 JEE,它指定作为最佳实践,必须以编程方式处理在上下文之外获取的资源。

于 2018-10-11T13:41:35.753 回答
2

和注释允许您为 bean定义生命周期回调@PostConstruct(有关详细信息,请参阅文档)。@PreDestroy

如果@PostConstruct注解的方法可能会抛出异常,您应该捕获它们并相应地处理资源的释放。考虑以下示例:

@SpringBootApplication
public class MySpringApplication {

    public static void main(String[] args) {
        SpringApplication.run(MySpringApplication.class, args);
    }

    @PostConstruct
    public void init() {
        System.out.println("@PostConstruct method executed");
        throw new RuntimeException();
    }

    @PreDestroy
    public void destroy() {
        System.out.println("@PreDestroy method executed");
    }
}

在这种情况下,@PreDestroy注释的方法将不会被执行。

于 2018-10-11T13:45:55.977 回答