如何在 Play 的静态方法中使用 play.cache.CacheApi!框架 2.4.2
Posted
技术标签:
【中文标题】如何在 Play 的静态方法中使用 play.cache.CacheApi!框架 2.4.2【英文标题】:How to use the play.cache.CacheApi in a static method in Play! Framework 2.4.2 【发布时间】:2015-08-05 13:29:08 【问题描述】:我有一个游戏框架应用程序,我已迁移它以在游戏框架 2.4.2 上运行。它为 javascript/html 前端提供 RESTful API。现在我在引入缓存时遇到了一些问题。
LibraryController(将 JSON/HTTP 请求转换为 JSON/HTTP 响应):
public class LibraryController extends Controller
public Result getBook(String isbn)
Book book = LibraryManager.getBook(isbn);
BookDto bookDto = DtoMapper.book2BookDtos(book);
return ok(Json.toJson(bookDto));
LibraryManager(将域模型请求转换为域模型响应):
public class LibraryManager
@Inject CacheApi cache;
public static Book getBook(String isbn)
Book book = cache.get(isbn);
// ...
我遇到的问题是我得到了
non-static variable cache cannot be referenced from a static context
我注入缓存的方式是按照Play 2.4.2 Cache API documentation。当我按照Play 2.2.x Cache API documentation 使用缓存时,我没有遇到这个问题。该版本有一个我可以调用的静态方法。
我该怎么办?我应该让 getBook 非静态应用一些单例模式吗?或者我应该以其他方式访问缓存吗?示例代码肯定会有所帮助!
【问题讨论】:
为什么你的 getBook 方法还是静态的? getBook 之所以是静态的,是因为实例化一个新对象只是为了服务请求和访问数据源(外部 Web API 等)似乎有点过分了。域模型类被实例化。推理无效吗? 在使用 Play 时,您通常不需要任何静态内容。只需在 Controller 中实例化 LibraryManager 并使 getBook 成为非静态的。 对于目前遇到这个问题的任何人,CacheApi 现在已被弃用 -@deprecated Deprecated as of 2.6.0. Use @link SyncCacheApi or @link AsyncCacheApi
【参考方案1】:
使用@Singleton
注解使Guice
知道LibraryManager
,从方法中删除静态关键字并将它们拉到接口:
@ImplementedBy(LibraryManager.class)
public interface ILibraryManager
//
@Singleton
public class LibraryManager implements ILibraryManager
@Inject
private CacheApi cache;
@Override
public Book getBook(String isbn)
Book book = cache.get(isbn);
// ...
现在您可以通过接口向控制器注入LibraryManager
:
public class LibraryController extends Controller
@Inject
private ILibraryManager libraryManager;
恭喜!您将LibraryManager
解耦并以适当的方式与Play 2.4
集成。
【讨论】:
我按照这个答案中的指南进行操作。除了上面的行,我发现我必须将routesGenerator := InjectedRoutesGenerator
添加到 build.sbt,因为我的控制器方法实际上也有 static
关键字。此外,我添加了import com.google.inject.ImplementedBy; @ImplementedBy(LibraryManager.class) public interface ILibraryManager
以配置要使用的实现。【参考方案2】:
在静态函数中获取 CacheApi.class 的实例。
public class LibraryManager
public static Book getBook(String isbn)
CacheApi cache = Play.current().injector().instanceOf(CacheApi.class);
Book book = cache.get(isbn);
// ...
【讨论】:
我会注意到这在 2.5.x 中已被弃用,并在 2.6.x 中被删除。它还引入了耦合,这违背了使用注射器的全部要点。也可以看到answer。以上是关于如何在 Play 的静态方法中使用 play.cache.CacheApi!框架 2.4.2的主要内容,如果未能解决你的问题,请参考以下文章
在 Play 框架 2.1.4 中将 Helpers.callAction 与没有静态方法的控制器一起使用
如何从 Play 框架中的 YAML 固定装置加载(静态嵌套)枚举值?