【问题标题】:Setting a global map in Grails在 Grails 中设置全局地图
【发布时间】:2014-01-17 15:14:55
【问题描述】:

我正在构建一个 Grails Web 应用程序,我在 BootStrap 中创建了一个地图并将其放置在 servletContext 中,以便让我的应用程序可以从任何地方使用它。平均而言,此映射应包含大约 1000 个带有字符串键和日期值的条目。

我想知道这是否会影响我的应用程序性能,是否有更好的地方来保存这张地图?我希望这张地图作为缓存机制工作。我想在其中放入一个唯一的密钥和一个日期,并能够通过传递密钥从任何地方(例如在控制器或服务类中)检索该日期对象。我正在考虑使用缓存机制来做到这一点,但还没有找到可以做到这种形式的缓存机制。如果有人可以推荐任何可以实现此目的的 Grails 插件,我将不胜感激。

P.S:是否可以使用缓存插件来做到这一点:http://grails-plugins.github.io/grails-cache/docs/manual/guide/usage.html#annotations

【问题讨论】:

  • 最好放到服务中,比如MyCachingService
  • 你能解释一下并详细说明你的答案吗?
  • 我的意思是服务可能是一个更好的地方,而不是 servletContext。更易于使用等
  • 所以如果我将它放在服务中,我所做的就是在启动时在引导程序中初始化服务,只要应用程序正在运行,它就会一直存在?
  • 是的,它将一直存在。您也可以将其标记为implements InitializingBean,因此在这种情况下您根本不需要引导程序

标签: caching grails web-applications map grails-plugin


【解决方案1】:

您可以使用服务来完成此任务。服务是一个单例,所以它会一直活着。而且从应用程序的其他部分访问要容易得多。准备应用启动数据,可以implements InitializingBean

敌人示例:

class MyCacheService implements InitializingBean {

  Map cache

  void afterPropertiesSet() {
     cache = [
        a: 1,
        b: 2,
        // .....
     ]
  }
}

【讨论】:

  • 我认为 Map 不是线程安全的,但是由于服务实例是单个的,因此不同的控制器尝试向 Map 缓存添加或删除项目应该没有任何问题,是吗?正确的 ? P.S:我必须让这个事务=true 还是保持原样?
  • 我需要制作 addToCache 和 getFromCache 之类的方法,我可以把它们都放在 "void afterPropertiesSet()" 之后吗?顺便说一句,这种方法有什么用?
  • 这是来自 Grails 网站:服务可以在多个不同的范围内注册,但默认是应用程序(或单例)范围,因此您的代码需要是线程安全的。参考:grails.org/version/Services/2
  • 在这里得到答案,Burt B 回答得很好grails.1312388.n4.nabble.com/…
  • 对不起,这只是示例如何使用服务。当然,你必须让它线程安全,等等。afterPropertiesSet()InitializingBean 接口的方法(确保你的类实现了它),它将在 bean 初始化时调用
【解决方案2】:

关于使 Map 缓存线程安全,我们可以使用 ConcurrentReaderHashMap 缓存,这样主要是并发读取,但独占写入。这样每个人都可以从服务中读取它,但不是每个人都可以同时写入或修改它。

可以在 addToCache 等方法上使用 Synchronized 块,这样两个控制器就不能同时写入,但对于 getFromCache 我们不需要。

Sample code for ConcurrentReaderHashMap

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-12-28
    • 2010-12-03
    • 1970-01-01
    • 2011-01-20
    • 2012-06-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多