如果Play控制器从请求中检索值(例如登录用户及其角色),那些值需要传递给所有层到控制器(例如服务层,DAO层等),这些值是什么?创建" threadlocal"的最好方法对象的类型,可以由应用程序中的任何类使用以检索那些" user"和" userRole"该特定请求的值?我试图避免将隐式参数添加到一堆方法中,并且Play Cache看起来不适合这里。如果所有代码都是异步的,那么播放的不同范围(会话,闪存等)也不会表现正常。控制器方法是异步的,服务方法返回Future等。" threadlocal"需要异步环境中的效果类型。
答案 0 :(得分:1)
不合适的替代品
这些替代方案可能没有帮助,因为它们假设在处理请求时所有功能都可以访问全局状态:
线程本地存储是一种技术,它有助于在单个线程中处理请求的应用程序,并在生成响应之前阻塞。虽然使用Play Framework可以实现这一点,但它通常不是最佳设计,因为Play的优势对于异步,非阻塞应用程序更有利。
会话和闪存旨在跨HTTP请求传输数据。它们并非全局可用于应用程序中的所有类;有必要跨函数调用传递修改后的请求以检索它们。
理论上可以使用缓存来传输此信息,但是每个请求都必须有一个唯一的密钥,并且必须在每个函数调用中传递此密钥。此外,有必要确保缓存数据在处理请求时不会被驱逐,即使缓存内存已满,也是如此。
可能适合的替代方案
假设控制器(可能通过Action
调用)检索安全数据(用户,角色等),并且控制器仅处理验证请求并生成响应,将域逻辑委派给a域对象(可能是服务对象):
使用调用堆栈:通过隐式参数将安全数据传递给所有需要它的函数。虽然问题在于找到替代方法,但这种方法明确了发送给被调用函数的内容,以及哪些函数需要这些数据,而不是求助于其他地方维护的状态。
使用OOP:将安全数据传递到域对象的构造函数中,并在域对象的方法中,从对象的实例中检索安全数据。
< / LI>使用actor:传递发送给actor的消息中的安全数据。
如果域对象的方法调用也需要安全数据的函数,则应用相同的模式:将其作为(可能是隐式的)参数,通过构造函数或消息传递。 / p>