Как использовать аспекты Spring AOP с Groovy и Grails, конкретный пример кэширования

Мы создали большой страховой полис и систему управления претензиями с использованием Grails и Groovy. Проблемы с производительностью замедляют работу сайта из-за того, что все "READS" извлекаются из базы данных, что не является необходимым, поскольку большая часть данных является статической. Мы хотим ввести простой кэш ключ / значение в слое Grails, но мы не хотим засорять существующий код кодом cache.get() и cache.set(), вместо этого мы хотим использовать аспекты.

Вот образец от нашего основного контроллера....

InsuranceMainController {
  def customer {
    //handles all URI mappings for /customer/customerId
  }

  def policy {
    //handles all URI mappings for /policy/policyId, 
  }

  def claim {
    //handles all URL mappings for /claim/claimId
  }

Что касается кеша, предположим, что на данный момент это простая карта с именем "кеш", которая доступна как объект глобальной области видимости, а объекты в кеше обрабатываются URI запроса...

cache.put("/customer/99876", customerObject)
cache.put("/policy/99-33-ARYT", policyObject) 

Возвращаясь к контроллеру, если мы просто засоряем код с помощью cache.get() / set(), чего мы хотим избежать при использовании Spring AOP, мы получим грязный код. Мы хотим добиться следующих функциональных возможностей с помощью приложений или просто с более простой и понятной реализацией...

InsuranceMainController {
  def customer {

    Object customer = cache.get(request.getRequestURI())
    if ( customer != null)
       //render response with customer object
    }else
       //get the customer from the database, then add to cache
       CustomerPersistenceManager customerPM = ...
       customer = customerPM.getCustomer(customerId)
       cache.put(request.getRequestURI(), customer)
    }
  }

Нам нужны примеры, которые показывают, как мы можем достичь вышеуказанной функциональности, используя Spring AOP или что-то более простое в Grails, избегая при этом мусора кода с помощью cache.get()/set(). Приветствуются предложения по реорганизации существующего контроллера, если это необходимо для правильной работы AOP.

заранее спасибо

1 ответ

Вместо того чтобы использовать AOP, вы могли бы адаптировать шаблон упрощения контроллера мистера Пола Вудса, чтобы перенести обработку кэша в один метод?

Нечто подобное может работать:

class InsuranceMainController {

  def customer = {
    Object customer = withCachedRef( 'customerId' ) { customerId ->
       CustomerPersistenceManager customerPM = ...
       customerPM.getCustomer(customerId)
    }
  }

  def policy = {
    //handles all URI mappings for /policy/policyId, 
    Object policy = withCachedRef( 'policyId' ) { policyId ->
       PolicyPersistenceManager policyPM = ...
       policyPM.getPolicy(policyId)
    }
  }

  // ...

  private def withCachedRef( String id, Closure c ) {
    Object ret = cache.get( request.requestURI )
    if( !ret ) {
      ret = c.call( params[ id ] )
      cache.put( request.requestURI, ret )
    }
    ret
  }
}

Тем не менее, я не проверял это вообще:-(Просто предложение альтернативы АОП

Другие вопросы по тегам