配置執行緒環境定義服務實例

您可以配置 ContextService 實例,以擷取受管理執行緒環境定義,並且套用它,以便在任何執行緒上呼叫指定的介面方法。

關於這項作業

Java™ EE 應用程式的最佳作法是避免直接管理自己的執行緒;因此,藉由 ContextService,您就可以將先前擷取的執行緒環境定義,建立到未受管理及受管理的執行緒中,以就地覆蓋任何執行緒環境定義。

伺服器會建立預設執行緒環境定義服務實例 (DefaultContextService),且會配置成至少擷取和傳播 classloaderContextjeeMetadataContextsecurityContext 元素。您可以配置執行緒環境定義延伸,來包含下列執行緒環境定義類型:

classloaderContext
將作業提交者的類別載入器提供給作業。如果環境定義類別載入器已序列化,類別載入器必須是應用程式中的執行緒環境定義類別載入器。如果是「OSGi Web 應用程式軟體組」,目前不支援類別載入器序列化。
jeeMetadataContext
將提交作業之應用程式元件的名稱空間提供給作業。
securityContext
您必須在 server.xml 檔中啟用 appSecurity-2.0 特性,以使用這種類型的執行緒環境定義。將作業提交者的呼叫端主題和呼叫主題提供給作業。其作法是利用 JAAS 登入模組,以提交者的 WSPrincipal 認證來登入。如需提交者主體中有哪些資訊不在安全環境定義中的詳細資料,請參閱 concurrent-1.0 特性限制
適用於 z/OS 平台
syncToOSThreadContext
將工作單元的 runAs 主體與作業系統身分同步化。
適用於 z/OS 平台
zosWLMContext
用來分類工作。

程序

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>
  • 含有 classloaderContextsecurityContext 的執行緒環境定義服務:
    <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);
    ...

指示主題類型的圖示 作業主題

檔名:twlp_config_contextservice.html