我们使用Grails和Groovy构建了一个大型的保险单和 claim 管理系统。性能问题使站点变慢,因为所有“读取”都从数据库中获取,这是不必要的,因为大多数数据都是静态的。我们想在Grails层中引入一个简单的键/值缓存,但是我们不想用cache.get()和cache.set()代码来填充现有代码,我们想使用方面。
这是来自我们的主 Controller 的示例。
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
}
就缓存而言,暂时假设它是一个名为“缓存”的简单Map,可以用作全局范围的对象,并且缓存中的对象由请求URI进行键控...
cache.put("/customer/99876", customerObject)
cache.put("/policy/99-33-ARYT", policyObject)
回到 Controller ,如果我们只是使用cache.get()/ set()乱码代码,这是我们要避免使用Spring AOP的方法,那么最终将导致混乱的代码。我们希望通过apsect或仅通过更简单,更清洁的实现来实现以下功能...
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正常工作,欢迎提出重构现有 Controller 的建议。
提前致谢
最佳答案
可以使用Mr Paul Woods' controller simplification pattern而不是使用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
}
}
但是,我还没有测试过它:-(只是AOP替代方案的建议
关于caching - 如何在Groovy和Grails中使用Spring AOP方面,特定的缓存示例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8387973/