2015-11-16 46 views
2

從請求作用域線程中,CompletableFuture必須由運行在執行程序中的任務完成。所提供的供應商使用具有會話範圍的域特定服務MessageService。該服務由Guice注入。Guice在執行CompletableFuture時拋出OutOfScopeException

public class MessageProcessingPage { 
    private MessageService messageService; 

    @Inject 
    public MessagProcessingPage (MessageService messageService) { 
     this.messageService = messageService; 
    } 

    // Called by request scoped thread. 
    public void onProcessMessagesButton() { 
     ExecutorService executorService = Executors.newFixedThreadPool(3); 
     CompletableFuture.supplyAsync(
     // Called from a thread from the threadpool. 
     () -> {return messageService.retrieveMessageMetadataSet(x, y);} 
     , executorService); 

     ... 

    } 

    ... 
} 

MessageService具有(會話範圍)MessageRestClient將其注入。

@SessionScoped 
public class MessageService { 
    private MessageRestClient messageRestClient; 

    @Inject 
    public MessageRestClient (MessageRestClient messageRestClient) { 
     this.messageRestClient = messageRestClient; 
    } 

    public MessageMetaDataSet retrieveMessageMetadataSet(x, y) { 
     List<MessageMetaData> listOfMetaData = messageRestClient.retrieve(x, y, z); 
     ... 
    } 

    ... 
} 

@SessionScoped 
public class MessageRestClient { 
    ... 
} 

當它試圖注入MessageRestClient時,Guice陷入困境。

java.util.concurrent.CompletionException: com.google.inject.ProvisionException: Unable to provision, see the following errors: 

1) Error in custom provider, com.google.inject.OutOfScopeException: Cannot access scoped [MessageRestClient]. Either we are not currently inside an HTTP Servlet request, or you may have forgotten to apply com.google.inject.servlet.GuiceFilter as a servlet filter for this request. 

ServletScopes閱讀的方法:public static <T> Callable<T> transferRequest(Callable<T> callable) 但我不明白的方式來使用它,因爲沒有可調用進來玩。你能幫我解決問題嗎?

回答

3

當處理在Guice一個servlet請求,GuiceFilter已設置適當的上下文(通過ThreadLocal),以便它可以知道在要求你,因此,正確應用作用域的照顧。用SessionScope註解的類的實例實際上是代理,它們可以從Guice訪問該請求和會話信息並相應地採取行動。

您發送至CompletableFuture的任務在Guice控件中的單獨線程中運行。沒有ThreadLocal可用,其中Guice可以從中獲取該信息,因此,沒有Request也沒有Session信息,是什麼意思,沒有[SessionScope。由於代理無法瞭解會話的任何內容,因此會引發您收到的錯誤。

ServletScopes.transferRequest方法應注入所需的信息,以便範圍工作。應該像這樣(但從未嘗試過):

Callable<MessageMetaDataSet> c = ServletScopes.transferRequest(
       () -> messageService.retrieveMessageMetadataSet(x, y)); 

    CompletableFuture.supplyAsync(
    () -> c.call() 
    , executorService); 
+1

其實它會值得一個新的線程,但因爲缺乏時間:我注意到在這種情況下應避免使用輔助注射。在'MessageService'中,我注入了一個'MessageFactory'(使用輔助注入),它被一個從任務調用的方法使用。吉斯也遇到了麻煩。由於我改變了普通工廠的輔助注射工廠,一切正常。 –

0

試試這個早期:吉斯@Inject所有作品罰款:



    import java.util.concurrent.CompletableFuture; 

    public class AsyncFire { 

     public static > void execAsync(Class asyncClass) { 
      T asyncInstance = AsyncInjector.getInjector().getInstance(asyncClass); //magic 
      CompletableFuture completableFuture = CompletableFuture.supplyAsync(asyncInstance); //business logic 
      completableFuture.exceptionally(asyncInstance); //if error 
      completableFuture.thenAccept(asyncInstance); //if success 
     } 

    } 



    public class ExampleAsync extends Async { 

     @Inject //it works 
     private EntityManager entityManager; 

     @Inject //it works 
     private DAO dao; //your 

    } 



    import java.util.function.Consumer; 
    import java.util.function.Function; 
    import java.util.function.Supplier; 

    public abstract class Async implements Supplier, Consumer, Function { 
     //... 
    } 



    import com.google.inject.Guice; 
    import com.google.inject.Injector; 
    import com.google.inject.persist.PersistService; 

    public final class AsyncInjector { 

     private static Injector injector = null; 

     public static Injector getInjector() { 
      if (injector == null) { 
       synchronized (AsyncInjector.class) { 
        if (injector == null) { 
         injector = Guice.createInjector(new MyGuiceModule()); //your guice module 
         PersistService service = injector.getInstance(PersistService.class); 
         service.start(); 
        } 
       } 
      } 
      return injector; 
     } 

    } 

希望這可以幫助別人!

相關問題