2017-09-08 110 views
2

我创建了Grails的3.1.16调用的测试基本应用程序,它具有两个服务,第一异步和计划服务(前FirstService)会话范围服务的调用方法第二会话范围服务(例如SessionScopeService。),如下:Grails的3.1.16 - 从预定服务

FirstService.groovy ”:

import org.springframework.scheduling.annotation.Async 
import org.springframework.scheduling.annotation.Scheduled 

class FirstService { 

    def sessionScopeService 
    boolean lazyInit = false 

    @Async 
    @Scheduled(cron="*/10 * * * * MON-FRI") 
    void firstServiceMethod() { 
     sessionScopeService.serviceMethod() 
    } 
} 

的Ses sionScopeService.groovy“:

class SessionScopeService { 

    static scope = "session" 
    static proxy = "true" 

    def serviceMethod() { 
     log.info("test OK") 
    } 
} 

应用程序无法启动,报告范围会话错误:

ERROR org.springframework.boot.SpringApplication - Application startup 
failed 
org.springframework.beans.factory.BeanCreationException: Error creating bean 

with name 'firstService': Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionScopeService ': 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. 
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:553) 
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482) 
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) 
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) 
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) 
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) 
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:778) 
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:839) 
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:538) 
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:118) 
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:760) 
at org.springframework.boot.SpringApplication.createAndRefreshContext(SpringApplication.java:360) 
at org.springframework.boot.SpringApplication.run(SpringApplication.java:306) 
at grails.boot.GrailsApp.run(GrailsApp.groovy:55) 
at grails.boot.GrailsApp.run(GrailsApp.groovy:375) 
at grails.boot.GrailsApp.run(GrailsApp.groovy:364) 
at grails.boot.GrailsApp$run.call(Unknown Source) 
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48) 
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113) 
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:133) 
at testservice.Application.main(Application.groovy:8) 
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionScopeService': 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. 
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:355) 
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) 
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireByName(AbstractAutowireCapableBeanFactory.java:1248) 
at org.grails.spring.beans.factory.OptimizedAutowireCapableBeanFactory.autowireByName(OptimizedAutowireCapableBeanFactory.java:160) 
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1198) 
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:543) 
... 20 common frames omitted 
Caused by: 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. 
at org.springframework.web.context.request.RequestContextHolder.currentRequestAttributes(RequestContextHolder.java:131) 
at org.springframework.web.context.request.SessionScope.get(SessionScope.java:91) 
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:340) 
... 25 common frames omitted 

我也试图对 'resources.groovy' 手动创建范围代理:

beans = { 

    sessionScopeServiceProxy(ScopedProxyFactoryBean) { 
     targetBeanName = 'sessionScopeService' 
     proxyTargetClass = true 
    } 
    } 

然后在FirstService注入了这个代理:

def sessionScopeServiceProxy 

但没有成功(“SessionScopeServiceProxy”的方法甚至没有被“FirstService”识别)。

我该如何解决这个问题? 感谢您的时间

回答

0

我猜你想使用每个“工作”运行时新SessionScopeService实例,因此,你应该使用“原型”的范围和手动得到的firstServiceMethod执行豆:grailsApplication.mainContext.getBean(SessionScopeService)。这样,每当您的“工作”开始时,将为该执行创建一个新的“SessionScopeService”。

+0

谢谢你的回答。不幸的是,我不能在“SessionScopeService”中使用“原型”会话:代码是一个更复杂项目的简单示例,其中“SessionScopeService”是一个必须具有“会话”范围的服务,因为它由多个会话同时调用(并且不仅仅来自单一服务的“第一服务”)。 – silviaB

+0

由于您的方法是从计划作业中调用的,因此您将永远不会将用户会话绑定到该线程,从而获得您在问题中粘贴的错误。您应该将代码移到另一个范围内的另一个服务中。 – bassmartin