Grails 2.4.x здесь.Как обернуть все методы обслуживания Grails с помощью Groovy закрытия?
У меня есть требование, что все методы всех моих Grails услуг, порожденные grails create-service <xyz>
, быть "обернутый"/перехвачены со следующей логикой:
try {
executeTheMethod()
} catch(MyAppException maExc) {
log.error(ExceptionUtils.getStackTrace(maExc))
myAppExceptionHandler.handleOrRethrow(maExc)
}
Где:
log.error(...)
является предоставленный SLF4J логгер, который вы получаете, когда вы комментируете свой класс с помощью аннотации@Slf4j
; иExceptionUtils
- это номер отorg.apache.commons:commons-lang3:3.4
; иmyAppExceptionHandler
имеет типcom.example.myapp.MyAppExceptionHandler
; и- Такое поведение существует (или имеет возможность существовать в том случае, если она должна быть явно называется как-то) для каждого метода, определенного в службе Grails
Так, очевидно, это обертка код должен включать import
заявления для этих классов.
Так, например, если у меня есть WidgetService
, который выглядит следующим образом:
class WidgetService {
WidgetDataService widgetDataService = new WidgetDataService()
Widget getWidgetById(Long widgetId) {
List<Widget> widgets = widgetDataService.getAllWidgets()
widgets.each {
if(it.id.equals(widgetId)) {
return it
}
}
return null
}
}
Затем после этого Groovy/Grails/закрытие магия происходит мне нужен код ведут себя так, как будто я написал это нравится:
import groovy.util.logging.Slf4j
import org.apache.commons.lang3.exception.ExceptionUtils
import com.example.myapp.MyAppExceptionHandler
@Slf4j
class WidgetService {
WidgetDataService widgetDataService = new WidgetDataService()
MyAppExceptionHandler myAppExceptionHandler = new MyAppExceptionHandler()
Widget getWidgetById(Long widgetId) {
try {
List<Widget> widgets = widgetDataService.getAllWidgets()
widgets.each {
if(it.id.equals(widgetId)) {
return it
}
}
return null
} catch(MyAppException maExc) {
log.error(ExceptionUtils.getStackTrace(maExc))
myAppExceptionHandler.handleOrRethrow(maExc)
}
}
}
Любые идеи относительно того, как я мог бы это достичь? Я волнуюсь, что чистая закрытие Groovy может каким-то образом вмешаться в то, что Grails делает со своими сервисами под капотом во время выполнения (так как это все классы, которые явно не распространяют родительский класс).
Вы задали [аналогичный вопрос год назад] (http://stackoverflow.com/questions/26407558/repetitive-try-catch-blocks-with-groovy-with-closure). Такой же подход можно использовать с небольшой настройкой. путем перемещения общей логики к признаку как реализации по умолчанию, а затем реализации признака в классах обслуживания. Другим подходом было бы использовать 'invokeMethod' для перехвата каждого метода в классе службы и обернуть их с помощью try/catch.Недостаток использования этого подхода заключается в том, что он должен повторяться в каждом классе обслуживания. Я считаю, что прежний подход будет более чистым и может быть статически скомпилирован. – dmahapatro
Спасибо @dmahapatro (+1) - да, я помню это и на самом деле имел это в виду, спрашивая об этом, но, как я уже сказал, я беспокоился о том, что Грайль может каким-то образом вмешаться. Если вы можете переместить свой комментарий в ответ с примером кода, показывающим один из предложенных вами подходов, я с радостью дам вам зеленый чек! – smeeb