Scala 我想创建一个全局字典,我也可以变异

Scala 我想创建一个全局字典,我也可以变异,scala,playframework,Scala,Playframework,如何在游戏中执行以下操作: 我需要在游戏中创建一个全局可访问的对象,以便我可以从我的所有控制器访问它 此对象将是用户对象的映射 如果查找失败,我想锁定,对查找执行db调用,然后在全局可访问对象(映射)中设置它 这可能吗?你可以作为一个单身汉来做这件事 在控制器的某个地方 @Inject private Users users; 您的实际班级: public class MyUsers implements Users .... Guice模块类: public class MyModule

如何在游戏中执行以下操作:

  • 我需要在游戏中创建一个全局可访问的对象,以便我可以从我的所有控制器访问它

  • 此对象将是用户对象的映射

  • 如果查找失败,我想锁定,对查找执行db调用,然后在全局可访问对象(映射)中设置它

  • 这可能吗?

    你可以作为一个单身汉来做这件事

    在控制器的某个地方

    @Inject
    private Users users;
    
    您的实际班级:

    public class MyUsers implements Users ....
    
    Guice模块类:

    public class MyModule extends AbstractModule {
    
        @Override
        protected void configure() {
            bind(Users.class).to(MyUsers.class).asEagerSingleton();
        }
    
    }
    
    在application.conf中

    一些文件:

    scala也是如此:


    如果您想这样做,我认为您可以使用DI和

    在其中一个guice模块中,可以有如下内容

    import scala.collection.concurrent
    
    @Provides @Named("localUserCache") @Singleton
    private def provideLocalUserCache(): concurrent.Map[Long, User] = {
      concurrent.TrieMap[Long, User]()
    }
    
    然后,在类中,在需要使用缓存的任何位置,注入该映射:

    import scala.collection.concurrent
    
    @Singleton
    class Application @Inject() (@Named ("localUserCache") val cache: concurrent.Map[Long, User], ... ) { ... }
    
    名为的
    @仅用于更清晰的目的,如果您只有一个并发映射的注入实例,则可以将其删除

    然后,您可以执行以下操作:

    cache.getOrElseUpdate(someId, getUserFromDb(someId))
    
    在这里,
    getUserFromDb(someId)
    仅在映射中不存在相应的键时执行。从文件中:

    如果指定的键不在映射中,则使用给定的thunk op计算其值并将其输入映射

    由于并发映射不能包含键或值的null,因此如果thunk op返回null,将引发NullPointerException

    另外,为了使事情更加简洁,您可以用封装映射的注入实例替换注入的映射。例如

    @Singleton
    class UserCache @Inject() {
      private val map: concurrent.Map[Long, User] = concurrent.TrieMap()
    
      def getUser(id: Long) = {
         map.getOrElseUpdate(id, getUserFromDb(id))
      }
    }
    

    可能:是的,一个好主意:可能不会。你为什么要这么做?每当需要用户对象时,我更喜欢常规的db调用。如果您遇到性能问题,请使用缓存。我希望缓存在本地存储,我不希望为此场景对缓存进行外部调用。必须问一个问题:为什么要这样做?这是可能的,因为它是2.3.x(我认为是4)之前的游戏的一部分。但它被删除了,因为DI方法现在受到青睐。因此,如果您实现这样的东西,您将不得不与框架作斗争,而这从来都不是一条愉快的道路。
    @Singleton
    class UserCache @Inject() {
      private val map: concurrent.Map[Long, User] = concurrent.TrieMap()
    
      def getUser(id: Long) = {
         map.getOrElseUpdate(id, getUserFromDb(id))
      }
    }