您如何处理无状态 Grails 服务中的共享数据

How do you deal with shared data in stateless grails service

我试图实现一个 grails SearchService 来索引特定文本并将其存储在内存中以便更快地查找。为了存储这些数据,我试图在服务中使用私有静态 属性 来存储数据,但 属性 随机重置值。重读文档后,我意识到这可能是因为 Grails 服务应该是无状态的,因为员工是单例模式。不过,不确定我是否了解静态变量的变化方式。 JVM 是否为每个线程加载单独的服务副本 classes?不确定我是否正在思考正在发生的事情。

尽管如此,既然我知道我不能依赖静态变量来存储应用程序范围的数据,那么在保持同步和避免竞争的同时存储和访问跨应用程序使用的数据的最佳方法是什么?


原因:java.lang.IllegalStateException:class [TEXTSTORE] 上的方法在 Grails 应用程序之外使用。如果 运行 在测试上下文中正确使用模拟 API 或 bootstrap Grails。 在 SearchService.buildIndex(SearchService.groovy:63) 在 SearchService$_indexAllDomains_closure2.doCall(SearchService.groovy:42) 在 SearchService.indexAllDomains(SearchService.groovy:41) 在 SearchService.$tt__rebuildIndex(SearchService.groovy:48) 在 SearchService.afterPropertiesSet(SearchService.groovy:35) ... 还有 4 个

您似乎对 Grails 中的服务有点困惑。服务(默认为单例)没有理由不能共享状态。服务在创建时填充一些缓存或索引数据以供多个调用者使用的情况并不少见。

大多数情况下,这是通过实现 org.springframework.beans.factory.InitializingBean 接口并使用在应用程序中创建服务(Spring bean)时调用的 afterPropertiesSet() 方法来完成的上下文和所有依赖项都已解决。

例如:

package com.example

import org.springframework.beans.factory.InitializingBean

class MyExampleService implements InitializingBean {
  private List data
  def otherService

  void afterPropertiesSet() {
    data = otherService.doSomethingToFetchData()
  }
  // .. other stuff
}

通过挂接到 bean 的生命周期,您可以相当确定即使在开发过程中(当您的服务因为您更改了一些代码而重新加载时)它仍然会有所需的数据。