2016-05-31 99 views
0

我有一個控制器和3個服務bean。我的目標是在請求範圍內從ExecutorService中併發3個併發REST服務。從ExecutorService使用彈簧'請求'範圍時產生異常

我得到異常之下,而其試圖在請求範圍內爲每個@autowired服務豆3次初始化豆。

能有人請幫我找出根本原因並解決問題。

Exception: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'scopedTarget.RestService1: Scope 'request' 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. 

代碼:

@RestController 
@RequestMapping(value = "/") 
public class TestController { 

    @Autowired 
    private RestService1 restService1; 
    @Autowired 
    private RestService2 restService2; 
    @Autowired 
    private RestService3 restService3; 
    @RequestMapping(value = "/testConcurency",method = RequestMethod.POST,consumes = MediaType.APPLICATION_JSON_VALUE,produces = MediaType.APPLICATION_JSON_VALUE) 
    public @ResponseBody testConcurency(@Valid @RequestBody TestRequest req, BindingResult errors) throws Exception { 

     ExecutorService executor = null; 
     Collection<Callable<TestResponse>> tasks = new ArrayList(); 
     tasks.add(restService1); 
     tasks.add(restService2); 
     tasks.add(restService3); 
     executor = Executors.newFixedThreadPool(tasks.size()); 
     List<Future<KycResponse>> list = executor.invokeAll(tasks,30, TimeUnit.SECONDS); 
    } 
} 


@Service 
@Scope(value=WebApplicationContext.SCOPE_REQUEST, proxyMode=ScopedProxyMode.TARGET_CLASS) 
public class RestService1 implements IThreadService, Callable<KycResponse>{ 
    @Override 
    public TestResponse call() throws Exception { 
     System.out.println("Hello from"+this); 
     // REST service will be called from here. 
    } 
} 

的web.xml我添加了一個監聽器

<listener> 
    <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class> 
</listener> 

謝謝!

+0

添加完整的堆棧跟蹤,請 – Jens

回答

0

當您使用的ExecutorService,該會的Runnable在不同的線程比web請求被執行,因此請求範圍是不是在其他線程訪問(因爲你沒有運行的請求那裏)。一個解決方案是將該服務bean的範圍改爲應用程序範圍(當然首先要確保它們被編程來處理該範圍,即沒有狀態等)。

+0

你好@dunny,理解你的觀點。改變這將導致許多文件現在編輯。我試過兩個選項,1)使其成爲Scope(「原型」)。但是我仍然得到每個服務bean的相同的對象引用。至少如果Spring創建新鮮的bean,每次都能解決我的問題。 2)爲每個服務bean創建局部變量,然後從服務bean入口變量拋出NullPointerException。 – Prasad