Spring Framework
  1. Spring Framework
  2. SPR-9852

@Resource injection of singleton in prototype using AnnotationConfigApplicationContext is not thread-safe

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Critical Critical
    • Resolution: Complete
    • Affects Version/s: 3.1.2
    • Fix Version/s: 3.1.3, 3.2 RC1
    • Component/s: Core:DI
    • Labels:
      None

      Description

      The attached test case demonstrates that @Resource of injection of singleton in prototype using AnnotationConfigApplicationContext is not thread-safe. However, changing @Resource to @Autowired seems to resolve the issue.

      Please see http://stackoverflow.com/questions/12700239/thread-safety-of-calling-bean-methods-from-returned-annonymous-inner-classes/12700284#comment17146235_12700284 for more details

      
      import java.util.ArrayList;
      import java.util.List;
      import java.util.concurrent.Callable;
      import java.util.concurrent.ExecutionException;
      import java.util.concurrent.ExecutorService;
      import java.util.concurrent.Executors;
      import java.util.concurrent.Future;
      import java.util.concurrent.TimeUnit;
      
      import javax.annotation.Resource;
      
      import org.junit.Test;
      import org.junit.runner.RunWith;
      import org.pentaho.di.core.util.Assert;
      import org.springframework.beans.factory.annotation.Autowired;
      import org.springframework.context.annotation.Bean;
      import org.springframework.context.annotation.Configuration;
      import org.springframework.context.annotation.Scope;
      import org.springframework.test.context.ContextConfiguration;
      import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
      import org.springframework.test.context.support.AnnotationConfigContextLoader;
      
      import com.oanda.bi.rm.test.AnnotationCallableConfigTest.Config;
      
      /**
       * @see http://stackoverflow.com/questions/12700239/thread-safety-of-calling-bean-methods-from-returned-annonymous-inner-classes/12700284#comment17146235_12700284
       * @see http://forum.springsource.org/showthread.php?130731-Thread-safety-of-calling-Bean-methods-from-returned-annonymous-inner-classes&p=426403#post426403
       * @author btiernay
       */
      @RunWith(SpringJUnit4ClassRunner.class)
      @ContextConfiguration(classes = { Config.class }, loader = AnnotationConfigContextLoader.class)
      public class AnnotationCallableConfigTest {
      
          @Autowired
          Callable<Holder> callable;
      
          @Test
          public void test() throws InterruptedException, ExecutionException {
              final int threads = 10;
              ExecutorService service = Executors.newFixedThreadPool( threads );
      
              List<Future<Holder>> futures = new ArrayList<>();
              for ( int i = 0; i < threads; i++ ) {
                  futures.add( service.submit( callable ) );
              }
      
              service.shutdown();
              service.awaitTermination( 1, TimeUnit.MINUTES );
      
              for ( Future<Holder> future : futures ) {
                  final Holder holder = future.get();
                  Assert.assertNotNull( holder.value );
              }
          }
      
          public static class Holder {
              // Changing this to @Autowired makes the test pass
              @Resource(name = "singleton")
              protected Integer value;
          }
      
          @Configuration
          public static class Config {
      
              @Bean
              public Integer singleton() {
                  return 1;
              }
      
              @Bean
              @Scope("prototype")
              public Holder prototype() {
                  return new Holder();
              }
      
              @Bean
              public Callable<Holder> function() {
                  return new Callable<Holder>() {
                      @Override
                      public Holder call() {
                          return prototype();
                      }
                  };
              }
      
          }
      }
      
      

        Issue Links

          Activity

          Hide
          Juergen Hoeller added a comment -

          This very much looks like a variation of SPR-9806 and seems to be covered by that fix already. In any case, your test consistently passes for me after that fix.

          Juergen

          Show
          Juergen Hoeller added a comment - This very much looks like a variation of SPR-9806 and seems to be covered by that fix already. In any case, your test consistently passes for me after that fix. Juergen

            People

            • Assignee:
              Juergen Hoeller
              Reporter:
              Bob Tiernay
              Last updater:
              Chris Beams
            • Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:
                Days since last comment:
                1 year, 28 weeks, 2 days ago