Grails服务类检测应用程序关闭的最佳方法是什么?

6

我有一个Grails服务类,需要在Tomcat应用服务器关闭时进行一些清理工作。

我在Grails文档中没有看到任何关于service.stop()或destroy()方法的内容,也没有找到实现任何应用程序生命周期监听器的方法。

那么,最好的方法是什么呢?

谢谢!

4个回答

8

您有几个选择

使您的服务实现org.springframework.beans.factory.DisposableBean

class MyService implements org.springframework.beans.factory.DisposableBean {

    void destroy() throws Exception {

    }
}

或者使用注释
class MyService {

    @PreDestroy
    private void cleanUp() throws Exception {

    }
 }

在我看来,注释选项更可取,因为您可以给析构函数方法命名比destroy更有意义,并且您的类公共API不会暴露Spring依赖。


谢谢,太好了!同意我更喜欢使用@PreDestroy,这样就不会暴露Spring依赖性,并且这样做更清晰明了。 - Dean Moses

6

grails-app/conf/BootStrap.groovy 可以在应用程序启动和停止时使用。

def init = {
  println 'Hello World!'
}

def destroy = {
  println 'Goodnight World!'
}

注意:在一些操作系统上,在开发模式下使用grails run-app时,按下CTL+C会强制终止JVM,而不会给出清洁关闭的机会,destroy闭包可能无法得到调用。此外,如果您的JVM被kill -9,则该闭包也不会运行。

这个回答并不适合这个问题,问题明确要求在应用程序关闭时通知服务。 虽然如果唯一的要求是在应用程序关闭时执行某些操作,那么这就足够了。 @Maricel的答案更接近答案,如果想将服务bean注入到引导程序中。 - Aditya T

1
我会尝试将服务注入到Bootstrap中,然后从销毁块调用该方法,因为销毁块在应用程序终止时执行,类似这样:
class BootStrap {

    def myService

    def init = {servletContext ->
    }

    def destroy = {
       myService.cleanUp()
    }
}

很好知道,Maricel。虽然在这种情况下,我喜欢像Don建议的那样使用@PreDestroy,因为它可以将清理与需要清理的服务清晰简单地联系起来。 - Dean Moses

0

这不完全是一个服务处理方法,但我最终做的是注册一个Spring Bean,该Bean具有在应用程序停止时调用的关闭方法。

首先,创建一个bean类,例如grails-app/utils/MyShutdownBean.groovy,其外观如下(类名或方法名并没有什么特别之处,可以使用任何你想要的名称):

class MyShutdownBean {
    public void cleanup() {
        // Do cleanup stuff
    }
}

然后在grails-app/conf/spring/resources.groovy文件中像这样注册bean:

beans = {
    myShutdownHook(MyShutdownBean) { bean ->
        bean.destroyMethod='cleanup'
    }
}

如果您只想在生产环境中进行清理,可以像这样注册它:
beans = {
    if (!grails.util.GrailsUtil.isDevelopmentEnv()) {
        myShutdownHook(MyShutdownBean) { bean ->
            bean.destroyMethod='cleanup'
        }
    }
}

这如何确保它在Tomcat死机时运行?如果Bean从未被实例化会怎样?如果它被垃圾回收了呢?那么它不会在您想要运行清理之前运行吗? - Gregg

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接