2016-09-05 5 views
2

내가 봄 부팅 컨트롤러 내에서 다음의 간단한 요청 방법이 비동기 방식의 '범위'요청 '현재의 thread 활성화되지 않은 "봄 부팅 :

@Autowired 
    private BillServ billServ; 
... 

@RequestMapping("/chrgcheck") 
public String chrgCheck() { 
    Future<Result> fut = null; 
    fut = billServ.useCheck(); 

while (!fut.isDone()) { 
     try { 
    Thread.sleep(100); 
    } catch (InterruptedException e) { 
    // TODO Auto-generated catch block 
    e.printStackTrace(); 
    } 
    } 
try { 
    if (fut.get().err ==0) { 
     return "OK"; 
    } else { 
     return "ERROR"; 
    } 
    } catch (InterruptedException e) { 
    // TODO Auto-generated catch block 
    e.printStackTrace(); 
    return "ERROR"; 
    } catch (ExecutionException e) { 
    // TODO Auto-generated catch block 
    e.printStackTrace(); 
    return "ERROR"; 
} 

} 

이 서비스 콩 billServ.useCheck의 방법을 비동기 호출();

@Component 
    @Scope(value="request", proxyMode=ScopedProxyMode.TARGET_CLASS) 
    public class Check { 

    public void checkMe(int i) { 
     System.out.println("checkMe:"+i); 

    } 
    } 

을 그래서 요청을 호출 할 때 "/ chrgcheck를"내가 요청에 따라 개별 콩 작동해야하기 때문에, 요청 범위의 빈 check.checkMe()의 또 다른 메소드를 호출

@Service 
    @Scope(value="request", proxyMode=ScopedProxyMode.TARGET_CLASS) 
    public class BillServ { 
    ... 
    @Async 
    public Future<Result> useCheck() { 
     Result res = new Result(); 

     System.out.println("Try-1"); 

     check.checkMe(1); 

     res.err=0; 
     return new AsyncResult<Result>(res); 
    } 

다음 오류가 발생합니다.

java.util.concurrent.ExecutionException: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'scopedTarget.check': 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. 
    at java.util.concurrent.FutureTask.report(FutureTask.java:122) 
    at java.util.concurrent.FutureTask.get(FutureTask.java:192) 
    at com.ric.web.BillingController.chrgCheck(BillingController.java:99) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:497) 
    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221) 
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:136) 
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:114) 
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827) 
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738) 
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85) 
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:963) 
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:897) 
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970) 
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861) 
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:622) 
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846) 
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:729) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:230) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) 
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) 

왜 그런가요? 내 프로젝트에서 무엇을 바로 잡아야합니까?

+2

비동기 방법에서는 요청 범위를 사용할 수 없습니다! – Ralph

+0

@Ralph 왜 대답 할 수 없으십니까? – nowszy94

답변

3

스프링 요청 범위 구현은 스레드 바운드입니다. 따라서 새 스레드 (즉, @Async)를 시작하면이 스레드는 요청에 바인딩되지 않으므로 스프링 요청 범위 구현이 실패합니다.

+0

요청 범위 Bean을 새 스레드에서 어떻게 사용할 수 있습니까? Spring은 향후 버전에서이 기능을 제공 할 계획이 있습니까? – Nadendla

0

프로토 타입을 제외한 기본 단일 범위 이외의 다른 범위가 필요한 bean을 정의해야합니다. 예 :

<bean id="shoppingCart" 
    class="com.xxxxx.xxxx.ShoppingCartBean" scope="session"> 
    <aop:scoped-proxy/> 
</bean>