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

Grails服务类检测应用程序关闭的最佳方法?,grails,groovy,service,application-lifecycle,Grails,Groovy,Service,Application Lifecycle,我有一个Grails服务类,当我的Tomcat应用服务器关闭时,它需要进行一些清理 我在Grails文档中没有看到关于service.stop()或destroy()方法的任何内容,也没有看到实现任何类型的应用程序生命周期侦听器的方法 最好的方法是什么 谢谢 这与服务处理方法不太一样,但我最后做的是用shutdown方法注册一个Springbean,当应用程序停止时调用该方法 首先,创建一个bean类,如grails-app/utils/MyShutdownBean.groovy,如下所示(类名

我有一个Grails服务类,当我的Tomcat应用服务器关闭时,它需要进行一些清理

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

最好的方法是什么


谢谢

这与服务处理方法不太一样,但我最后做的是用shutdown方法注册一个Springbean,当应用程序停止时调用该方法

首先,创建一个bean类,如
grails-app/utils/MyShutdownBean.groovy
,如下所示(类名或方法名没有什么神圣之处,可以随意使用):

然后在
grailsapp/conf/spring/resources.groovy中注册bean,如下所示:

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

    def myService

    def init = {servletContext ->
    }

    def destroy = {
       myService.cleanUp()
    }
}
如果只想在生产环境中进行清理,可以按如下方式注册:

beans = {
    if (!grails.util.GrailsUtil.isDevelopmentEnv()) {
        myShutdownHook(MyShutdownBean) { bean ->
            bean.destroyMethod='cleanup'
        }
    }
}

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

def init = {
  println 'Hello World!'
}

def destroy = {
  println 'Goodnight World!'
}

注意:在某些操作系统的
CTL+C
上使用开发模式
grailsrun-app
时,将杀死JVM,而不会完全关闭,并且可能不会调用destroy闭包。另外,如果您的JVM获得了
kill-9
,那么闭包也不会运行。

您有两个选择

让您的服务实现
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依赖项我会尝试将服务注入引导,然后从destroy块调用该方法,由于销毁块是在应用程序终止时执行的,因此如下所示:

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

    def myService

    def init = {servletContext ->
    }

    def destroy = {
       myService.cleanUp()
    }
}

如何确保它在Tomcat死后运行?如果bean从未被实例化呢?如果它是垃圾收集的呢?然后它会在你想要之前进行你的清理吗?谢谢,太好了!我同意我更喜欢@PreDestroy,这样就不会暴露Spring的依赖性,而且这更清楚地说明了发生了什么。很高兴知道,Maricel。虽然在这种情况下,我喜欢按照Don的建议使用@PreDestroy,因为它非常干净,只是将清理与需要清理的服务联系起来。这个答案不适合这个问题,这个问题特别要求在应用程序关闭时通知服务。虽然若唯一的要求是在应用程序关闭时做一些事情,那个就足够了@如果要将服务bean注入引导,Maricel的答案更接近于答案。