【发布时间】:2011-07-30 08:20:33
【问题描述】:
我有一个 Grails 服务类,当我的 Tomcat 应用程序服务器关闭时需要进行一些清理。
我在 Grails 文档中没有看到任何关于 service.stop() 或 destroy() 方法,或者实现任何类型的应用程序生命周期侦听器的方法。
最好的方法是什么?
谢谢!
【问题讨论】:
标签: grails groovy service application-lifecycle
我有一个 Grails 服务类,当我的 Tomcat 应用程序服务器关闭时需要进行一些清理。
我在 Grails 文档中没有看到任何关于 service.stop() 或 destroy() 方法,或者实现任何类型的应用程序生命周期侦听器的方法。
最好的方法是什么?
谢谢!
【问题讨论】:
标签: grails groovy service application-lifecycle
这与服务处置方法不太一样,但我最终做的是注册一个 Spring 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'
}
}
}
【讨论】:
grails-app/conf/BootStrap.groovy 可以在应用启动和停止时使用。
def init = {
println 'Hello World!'
}
def destroy = {
println 'Goodnight World!'
}
注意:当在某些操作系统的CTL+C 上使用开发模式grails run-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 {
}
}
IMO,注释选项更可取,因为您可以为析构函数指定一个比 destroy 更有意义的名称,并且您的类公共 API 不会暴露 Spring 依赖项
【讨论】:
我会尝试将服务注入 Bootstrap,然后从销毁块调用该方法,因为销毁块是在应用程序终止时执行的,如下所示:
class BootStrap {
def myService
def init = {servletContext ->
}
def destroy = {
myService.cleanUp()
}
}
【讨论】: