使用 Grails 2.4.5 我有以下服务:
class CartService {
static scope = 'session'
static proxy = true
def items = []
def getItemCount() {
items.size()
}
}
我想在 Controller 中使用此服务:
class CartController {
def cartService // unique per session
def addItem = {
cartService.items << new CartItem(product: Product.get(params.id))
}
}
我尝试了 Grails scoped-proxy plugin 的 0.3 版本。但我收到以下错误:
Error creating bean with name 'cartService': Scope 'session' is not active for the current thread; consider defining a scoped proxy for this bean if you intend to refer to it from a singleton; nested exception is java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet/DispatcherPortlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.
Line | Method
->> 262 | run in java.util.concurrent.FutureTask
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| 1145 | runWorker in java.util.concurrent.ThreadPoolExecutor
| 615 | run . . . in java.util.concurrent.ThreadPoolExecutor$Worker
^ 745 | run in java.lang.Thread
Caused by BeanCreationException: Error creating bean with name 'cartService': Scope 'session' is not active for the current thread; consider defining a scoped proxy for this bean if you intend to refer to it from a singleton; nested exception is java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet/DispatcherPortlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.
->> 262 | run in java.util.concurrent.FutureTask
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| 1145 | runWorker in java.util.concurrent.ThreadPoolExecutor
| 615 | run . . . in java.util.concurrent.ThreadPoolExecutor$Worker
^ 745 | run in java.lang.Thread
Caused by IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet/DispatcherPortlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.
->> 262 | run in java.util.concurrent.FutureTask
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| 1145 | runWorker in java.util.concurrent.ThreadPoolExecutor
| 615 | run . . . in java.util.concurrent.ThreadPoolExecutor$Worker
^ 745 | run in java.lang.Thread
如何在 Grails Controller 中包含具有 session 范围的服务?
最佳答案
看起来您可能发现了 Grails 2.4.x 插件的一两个问题(并且也报告了)。如果是这种情况,您可以引用插件作者的博文:Scoped Services & Proxies in Grails .
他在那里展示了如何在没有插件的情况下做到这一点。我试了一下,它可以在 2.4.5 中运行。
资源.groovy:
import org.springframework.aop.scope.ScopedProxyFactoryBean
beans = {
cartServiceProxy(ScopedProxyFactoryBean) {
targetBeanName = 'cartService'
proxyTargetClass = true
}
}
代理是手动完成的,因此您可以删除静态代理
class CartService {
static scope = 'session'
def items = []
def getItemCount() {
items.size()
}
}
Controller 然后引用代理
class CartController {
def cartServiceProxy
...
}
请注意,有一个令人困惑的地方(至少对我来说)是 Controller Documentation for 2.4.x说默认范围是 prototype
但在描述 Scoped Services 的部分中它说从 2.3.x 开始,默认 Controller 范围是 singleton
。
希望这有帮助。
更新:为了澄清一点,在 Grails 2.3 之后,默认 Controller 作用域仍然是 prototype
,但是当 Grails 生成新应用程序时,会生成将默认 Controller 作用域设置为 singleton
的配置(如果可能的话,这确实是您应该追求的目标,就像下面 Burt 所说的那样)。
在 Config.groovy 中生成配置
// The default scope for controllers. May be prototype, session or singleton.
// If unspecified, controllers are prototype scoped.
grails.controllers.defaultScope = 'singleton'
关于java - 在 Grails Controller 中包含具有 session 范围的服务?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32297023/