Перехватывать вызовы сервисных методов с помощью метапрограммирования в groovy / grails - PullRequest
1 голос
/ 11 февраля 2010

У меня есть несколько сервисов Grails, которые вызываются из кода Flex с использованием интеграции Spring BlazeDS. Я хотел добавить некоторые общие отладочные журналы, используя Groovy метакласс. У меня есть следующее в классе начальной загрузки:

class MyBootStrap {

def grailsApplication

def init = { servletContext ->
        initServiceCallLogging()
}

def destroy = {
}

private def initServiceCallLogging() {
    grailsApplication.serviceClasses.each { serviceClass ->
        serviceClass.metaClass.invokeMethod = { name, args ->
            log.debug "Method $name invoked"
            def metaMethod = delegate.metaClass.getMetaMethod(name, args)
            def result = metaMethod.invoke(delegate, args)
            return result

        }
    }
}
}

Это прекрасно работает, если метод Service вызывается, например, из. контроллер Grails или служба, но при непосредственном вызове из Flex (через BlazeDS) вызовы метода не перехватываются.

Кто-нибудь знает, как это можно решить или это невозможно с помощью метапрограммирования и следует ли использовать Spring AOP?

Thx

Ответы [ 3 ]

1 голос
/ 10 декабря 2010

Это работает для меня. Возможно из-за новой версии плагина BlazeDS.

Одно предложение: Вместо написания

log.debug` "Method $name invoked

Я использую:

delegate.log.debug "Service call: ${name}(${args})"

Преимущество заключается в том, что регистратор записывает класс, в котором ведется регистрация, вместо начальной загрузки.

1 голос
/ 11 февраля 2010

Я понятия не имею, почему перехват, который вы пытаетесь вызвать, вызывается только в некоторых случаях, код выглядит хорошо для меня. Возможно, стоит попробовать один или оба из следующих

Предложение 1

Переместите метапрограммирование из Bootstrap в плагин. Я слышал, что метапрограммирование, подобное этому, всегда должно выполняться при закрытии doWithDynaicMethods плагина, а не Bootstrap, потому что Bootstrap не всегда (всегда) выполняется при перезагрузке приложения во время выполнения.

Предложение 2

Вместо перехвата методов путем реализации invokeMethod в метаклассе каждого сервиса, вы можете вместо этого реализовать invokeMethod для каждого класса напрямую и заставить сервис реализовать GroovyInterceptable. Например, заменить:

class MyService {
// implementation
}

С:

class MyService implements GroovyInterceptable {

  def invokeMethod(String name, args) {
    log.debug "Method $name invoked"

    def originalMethod = Car.metaClass.getMetaMethod(name, args)
    originalMethod.invoke(this, args)
  }
}

Очевидная проблема с этим состоит в том, что вам потребуется добавить вышеупомянутый шаблонный шаблон также ко всем вашим услугам. Но если это сработает, возможно, вы сможете использовать его в качестве отправной точки для решения DRYer.

0 голосов
/ 10 августа 2010

Решение другая проблема Я сталкивался, также решил эту проблему. Используйте явное определение своих сервисов в flex-servlet.xml вместо аннотации @RemotingDestination, а метапрограммирование также работает для сервисов, вызываемых из BlazeDS.

...