title: Spring MVC: How to use a request-scoped bean inside a spawned thread?
body: <p>In a Spring MVC application, I have a request-scoped bean. I inject this bean somewhere. There, the HTTP-request serving thread could possibly spawn a new thread.</p>
  
  <p>But whenever I try accessing the request-scoped bean from the newly spawned thread, I get a <code>org.springframework.beans.factory.BeanCreationException</code> (see stack trace below).<br>
  Accessing the request-scoped bean from the HTTP request thread works fine.</p>
  
  <p><strong>How can I make a request-scoped bean available to threads spawned by the HTTP request thread?</strong></p>
  
  <hr>
  
  <h2>Simple setup</h2>
  
  <p>Get the following code snippets running. Then start up a server, for instance at <a href="http://example.com:8080">http://example.com:8080</a>.<br>
  When accessing <a href="http://example.com:8080/scopetestnormal">http://example.com:8080/scopetestnormal</a>, each time a request is made to this address, <code>counter</code> is incremented by 1 (noticeable via logger output). :) Super!</p>
  
  <p>When accessing <a href="http://example.com:8080/scopetestthread">http://example.com:8080/scopetestthread</a>, each time a request is made to this address, the mentioned exceptions are thrown. :(. No matter what chosen <code>ScopedProxyMode</code>, this happens for both CGLIB-based <em>and</em> 
  JDK-dynamic-proxy-interface-based request-scoped beans</p>
  
  <p>Configuration file</p>
  
  <pre><code>package com.example.config
  
  @Configuration
  @ComponentScan(basePackages = { "com.example.scopetest" })
  public class ScopeConfig {
  
      private Integer counter = new Integer(0);
  
      @Bean
      @Scope(value = "request", proxyMode = ScopedProxyMode.TARGET_CLASS)
      public Number counter() {
          counter = new Integer(counter.intValue() + 1);
          return counter;
      }
  
  
      /* Adding a org.springframework.social.facebook.api.Facebook request-scoped bean as a real-world example why all this matters
      @Bean
      @Scope(value = "request", proxyMode = ScopedProxyMode.INTERFACES)
      public Facebook facebook() {
      Connection&lt;Facebook&gt; facebook = connectionRepository()
              .findPrimaryConnection(Facebook.class);
      return facebook != null ? facebook.getApi() : new FacebookTemplate();
      }
      */
  
      ...................
  
  }
  </code></pre>
  
  <p>Controller file</p>
  
  <pre><code>package com.example.scopetest;
  
  import javax.inject.Inject;
  
  import org.slf4j.Logger;
  import org.slf4j.LoggerFactory;
  
  import org.springframework.social.facebook.api.Facebook;
  import org.springframework.social.facebook.api.FacebookProfile;
  import org.springframework.stereotype.Controller;
  
  import org.springframework.web.bind.annotation.RequestMapping;
  
  @Controller
  public class ScopeTestController {
  
      //@Inject
      //private Facebook facebook;
  
      @Inject
      private Number counter;
  
      private static final Logger logger = LoggerFactory
              .getLogger(ScopeTestController.class);
  
      @RequestMapping(value = "/scopetestnormal") 
      public void scopetestnormal() {
          logger.debug("About to interact with a request-scoped bean from HTTP request thread");
          logger.debug("counter is: {}", counter);
  
          /* 
           * The following also works
           * FacebookProfile profile = facebook.userOperations().getUserProfile();
           * logger.debug("Facebook user ID is: {}", profile.getId());    
           */
      }
  
  
  
      @RequestMapping(value = "/scopetestthread")
      public void scopetestthread() {
          logger.debug("About to spawn a new thread");
          new Thread(new RequestScopedBeanAccessingThread()).start();
          logger.debug("Spawned a new thread");
      }
  
  
      private class RequestScopedBeanAccessingThread implements Runnable {
  
          @Override
          public void run() {
              logger.debug("About to interact with a request-scoped bean from another thread. Doomed to fail.");          
              logger.debug("counter is: {}", counter);
  
              /*
               * The following is also doomed to fail
               * FacebookProfile profile = facebook.userOperations().getUserProfile();
               * logger.debug("Facebook user ID is: {}", profile.getId());        
               */
          }
  
      }
  
  }
  </code></pre>
  
  <hr>
  
  <p>Stack trace for CGLIB-based request-scoped bean (<code>proxyMode = ScopedProxyMode.TARGET_CLASS</code>)</p>
  
  <pre><code>SLF4J: Failed toString() invocation on an object of type [$java.lang.Number$$EnhancerByCGLIB$$45ffcde7]
  org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'scopedTarget.counter': 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 org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:342)
      at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
      at org.springframework.aop.target.SimpleBeanTargetSource.getTarget(SimpleBeanTargetSource.java:33)
      at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.getTarget(Cglib2AopProxy.java:654)
      at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:605)
      at $java.lang.Number$$EnhancerByCGLIB$$45ffcde7.toString(&lt;generated&gt;)
      at org.slf4j.helpers.MessageFormatter.safeObjectAppend(MessageFormatter.java:304)
      at org.slf4j.helpers.MessageFormatter.deeplyAppendParameter(MessageFormatter.java:276)
      at org.slf4j.helpers.MessageFormatter.arrayFormat(MessageFormatter.java:230)
      at ch.qos.logback.classic.spi.LoggingEvent.&lt;init&gt;(LoggingEvent.java:114)
      at ch.qos.logback.classic.Logger.buildLoggingEventAndAppend(Logger.java:447)18:09:48.276 container [Thread-16] DEBUG c.g.s.c.c.god.ScopeTestController - counter is: [FAILED toString()]
  
      at ch.qos.logback.classic.Logger.filterAndLog_1(Logger.java:421)
      at ch.qos.logback.classic.Logger.debug(Logger.java:514)
      at com.example.scopetest.ScopeTestController$RequestScopedBeanAccessingThread.run(ScopeTestController.java:58)
      at java.lang.Thread.run(Thread.java:722)
  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.AbstractRequestAttributesScope.get(AbstractRequestAttributesScope.java:40)
      at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:328)
      ... 14 more
  </code></pre>
  
  <hr>
  
  <p>Stack trace for JDK-dynamic-proxy-interface-based request-scoped bean (<code>proxyMode = ScopedProxyMode.INTERFACES</code>)</p>
  
  <pre><code>Exception in thread "Thread-16" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'scopedTarget.facebook': 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 org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:342)
      at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
      at org.springframework.aop.target.SimpleBeanTargetSource.getTarget(SimpleBeanTargetSource.java:33)
      at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:182)
      at $Proxy28.userOperations(Unknown Source)
      at com.example.scopetest.ScopeTestController$PrintingThread.run(ScopeTestController.java:61)
      at java.lang.Thread.run(Thread.java:722)
  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.AbstractRequestAttributesScope.get(AbstractRequestAttributesScope.java:40)
      at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:328)
      ... 6 more
  </code></pre>