配置執行緒環境定義服務實例
您可以配置 ContextService 實例,以擷取受管理執行緒環境定義,並且套用它,以便在任何執行緒上呼叫指定的介面方法。
關於這項作業
伺服器會建立預設執行緒環境定義服務實例 (DefaultContextService),且會配置成至少擷取和傳播 classloaderContext、jeeMetadataContext 和 securityContext 元素。您可以配置執行緒環境定義延伸,來包含下列執行緒環境定義類型:
- classloaderContext
- 將作業提交者的類別載入器提供給作業。如果環境定義類別載入器已序列化,類別載入器必須是應用程式中的執行緒環境定義類別載入器。如果是「OSGi Web 應用程式軟體組」,目前不支援類別載入器序列化。
- jeeMetadataContext
- 將提交作業之應用程式元件的名稱空間提供給作業。
- securityContext
- 您必須在 server.xml 檔中啟用 appSecurity-2.0 特性,以使用這種類型的執行緒環境定義。將作業提交者的呼叫端主題和呼叫主題提供給作業。其作法是利用 JAAS 登入模組,以提交者的 WSPrincipal 認證來登入。如需提交者主體中有哪些資訊不在安全環境定義中的詳細資料,請參閱 concurrent-1.0 特性限制。
程序
在 server.xml 檔中啟用執行緒環境定義服務。執行緒環境定義服務可在 <concurrent-1.0> 特性之下提供。
<featureManager>
<feature>concurrent-1.0</feature>
</featureManager>
範例
在 server.xml 檔中配置執行緒環境定義服務實例:
- 以 concurrent/threadContextSvc1 名稱登錄在 JNDI 中,並且只擷取和傳播 jeeMetadataContext 的執行緒環境定義服務:
<contextService id="threadContextSvc1" jndiName="concurrent/${id}"> <jeeMetadataContext/> </contextService>
- 含有 classloaderContext 和 securityContext 的執行緒環境定義服務:
<contextService jndiName="concurrent/threadContextSvc2"> <classloaderContext/> <securityContext/> </securityContext/>
- 從 threadContextSvc1 繼承 jeeMetadataContext,並且新增
securityContext 的執行緒環境定義服務:
<contextService jndiName="concurrent/threadContextSvc3" baseContextRef="threadContextSvc1"> <securityContext> </contextService>
查閱預設環境定義服務的範例:
ContextService threadContextSvc =
(ContextService) new InitialContext().lookup(
"java:comp/DefaultContextService");
myContextualAsyncCallback = threadContextSvc.createContextualProxy(
myAsyncCallback, MyAsyncCallback.class);
doSomethingAsync(arg1, arg2, myContextualAsyncCallback);
將執行緒環境定義服務實例注入應用程式元件中(使用 @Resource),或利用資源環境參照 (resource-env-ref) 來進行查閱的範例。
- 使用 @Resource 的範例:
@Resource(lookup="concurrent/threadContextSvc1") ContextService threadContextSvc1; ... Callable<Integer> processSalesOrderCompletion = new Callable<Integer>() { public Integer call() throws Exception { DataSource ds = (DataSource) new InitialContext().lookup("java:comp/env/jdbc/ds1"); ...update various database tables return isSuccessful; } }; // capture thread context of current application component execProps = Collections.singletonMap(ManagedTask.TRANSACTION, ManagedTask.USE_TRANSACTION_OF_EXECUTION_THREAD); processSalesOrderCompletion = (Callable<Boolean>) threadContextSvc1.createContextualProxy(processSaleCompletion, execProps, Callable.class); //later from a different application component tran.begin(); ... successful = processSalesOrderCompletion.call(); if (successful) tran.commit(); else tran.rollback();
- 在 web.xml 檔中指定 resource-env-ref 的範例:
<resource-env-ref> <resource-env-ref-name>concurrent/threadContextSvc3</resource-env-ref-name> <resource-env-ref-type>javax.enterprise.concurrent.ContextService</resource- env-ref-type> </resource-env-ref>
- 使用資源環境參照來查閱的範例:
ContextService threadContextSvc3 = (ContextService) new InitialContext().lookup("java:comp/env/concurrent/threadContextSvc3"); Runnable updateAndGetNextFromDatabase = threadContextSvc3.createContextualProxy (new Runnable() { public void run() { DataSource ds = (DataSource) new InitialContext().lookup("java:comp/env/jdbc/ds1"); ... update the database and get next item to process } }, Runnable.class); barrier = new CyclicBarrier(3, updateAndGetNextFromDatabase); ...