EJB 비동기 메소드를 호출하는 클라이언트 코드 개발
이 주제에 있는 샘플 코드를 사용하여 EJB 비동기 메소드를 호출하는 클라이언트 코드를 개발할 수 있습니다.
시작하기 전에
public interface AcmeRemoteInterface {
void fireAndForgetMethod ();
Future<Integer> methodWithResults() throws AcmeException1, AcmeException2;
}
@Stateless
@Remote(AcmeRemoteInterface.class)
@Asynchronous
public class AcmeAsyncBean {
public void fireAndForgetMethod () {
// do non-critical work
}
public Integer methodWithResults() {
Integer result;
// do work, and then return results
return result;
}
}
이 태스크 정보
프로시저
- 종종 실행 후 잊음 메소드라고 부르는, 결과가 리턴되지 않는
비동기 메소드를 호출하는 클라이언트 코드를 작성하십시오.
이 유형의 비동기 메소드가 애플리케이션 예외가 될 수 없습니다.
그러나, 해결해야 하는 시스템 예외가 발생할 수 있습니다.
@EJB AcmeRemoteInterface myAsyncBean; try { myAsyncBean.fireAndForgetMethod(); } catch (EJBException ejbex) { // Asynchronous method never dispatched, handle system error }
- 결과가 리턴되지 않는 비동기 메소드를 호출하는 클라이언트
코드를 작성하십시오.
- 클라이언트가 결과를 수신하기 위해 최고 5초(클라이언트
스레드가 이 시간 동안 차단됨) 동안 기다리는 비동기 메소드를
호출하는 클라이언트 코드를 작성하십시오. 예외 처리 요구사항은
이전 단계에서와 동일합니다. 예를 들어 다음과 같습니다.
myResult = myFutureResult.get(5, TimeUnit.SECONDS);
- 결과를 즉시 얻지 못하는 비동기 메소드를 호출하는
클라이언트 코드를 작성하십시오. 메소드가 실행된 후 클라이언트가
결과를 검색합니다. 이 체계는 클라이언트 스레드가
차단하지 못하게 하며, 클라이언트는 결과를 폴링하는 동안 다른
작업을 자유롭게 실행할 수 있습니다. 예외 처리 요구사항은 이전
단계에서와 동일합니다. 이 예에서, 클라이언트는 주기적으로
Future<V> 오브젝트를 폴링하여 비동기 메소드가 실행을
완료한 시기를 판별합니다. 예를 들어 다음과 같습니다.
while (!myFutureResult.isDone()) { // Execute other work while waiting for the asynchronous method to complete. } // This call is guaranteed not to block because isDone returned true. myResult = myFutureResult.get();
- 클라이언트가 결과를 수신하기 위해 최고 5초(클라이언트
스레드가 이 시간 동안 차단됨) 동안 기다리는 비동기 메소드를
호출하는 클라이언트 코드를 작성하십시오. 예외 처리 요구사항은
이전 단계에서와 동일합니다. 예를 들어 다음과 같습니다.
- 애플리케이션 예외를 처리할 클라이언트 코드를 작성하십시오. 클라이언트 코드는 Future<V> 오브젝트에서
애플리케이션 예외를 리턴하는 비동기 메소드를
호출합니다. 다음 예는 발생한 애플리케이션 예외를 판별하기
위해 필요한 예외 처리 코드를 보여줍니다.
@EJB AcmeRemoteInterface myAsyncBean; Future<Integer>>myFutureResult = null; Integer myResult = null; try { myFutureResult = myAsyncBean.methodWithResults(); } catch (EJBException ejbx) { // Asynchronous method never dispatched, handle exception } // Method is eventually dispatched. Wait for results. try { myResult = myFutureResult.get(); } catch (ExecutionException ex) { // Determine which application exception that occurred during the // asynchronous method call. Throwable theCause = ex.getCause(); if (theCause instanceof AcmeException1) { // Handle AcmeException1 } else if (theCause instanceof AcmeException2) { // Handle AcmeException2 } else { // Handle other causes. } } catch ( ... ) { // Handle other exception. }
- 실행 중에 비동기 메소드 호출에 의해 발생한 시스템 예외를
식별하는 클라이언트 코드를 작성하십시오.
다음 예는 시스템 예외가 발생했는지 여부를 판별하기
위해 필요한 예외 처리 코드를 보여줍니다.
@EJB AcmeRemoteInterface myAsyncBean; Future<Integer>>myFutureResult = null; Integer myResult = null; try { myFutureResult = myAsyncBean.methodWithResults(); } catch (EJBException ejbx) { // Asynchronous method was not dispatched; handle exception. } // Method will eventually be dispatched so block now and wait for results try { myResult = myFutureResult.get(); } catch (ExecutionException ex) { // Find the exception class that occurred during the asynchronous method Throwable theCause = ex.getCause(); if (theCause instanceof EJBException) { // Handle the EJBException that might be wrapping a system exception // which occurred during the asynchronous method execution. Throwable theRootCause = theCause.getCause(); if (theRootCause != null) { // Handle the system exception } } else ... // handle other causes } catch (...) { // handle other exceptions }
- 선택적으로 비동기 메소드 호출을 취소하기 위한 클라이언트 코드를
작성하십시오. 이 시도가 성공하는 경우, Future.isCancelled 메소드가
true를 리턴하고 Future.get 메소드는 CancellationException이 됩니다. 다음 예는 비동기 메소드 호출을
취소하기 위해 필요한 코드를 보여줍니다.
@EJB AcmeRemoteInterface myAsyncBean; Future<Integer> myFutureResult = myFutureResult.methodWithResults(); Integer myResult; if (myFutureResult.cancel(true)) { // Asynchronous method was not dispatched. } else { // Asynchronous method already started executing. The bean can still check // whether an attempt was made to cancel the call. } if (myFutureResult.isCancelled()) { // Asynchronous method call did not start executing because the cancel // method returned true in a previous line of the example. } try { myResult = myFutureResult.get(); } catch (CancellationException ex) { // Handle the exception that occurs because the cancel method returned true // in a previous line of the example. }
- 선택적으로 클라이언트가 비동기 메소드 호출을 취소하려고
시도했는지 여부를 검사하는 Bean 코드를 작성하십시오.
다음 예는 클라이언트가 비동기 메소드 호출을 취소하려고
시도했는지 여부를 검사하기 위해 필요한 Bean 코드를
보여줍니다. 클라이언트가 작업을 취소하려고 시도한 경우, SessionContext.wasCancelCalled
메소드는 true를 리턴하고 Bean 코드는 불필요한 작업을 피할 수 있습니다.
@Resource SessionContext myContext; public Future<Integer> methodWithResults() { for (int i = 0; i < 3; i++) { // Do one piece of long-running work. // Before continuing, check whether the client attempted to cancel this work. if (myContext.wasCancelCalled()) { throw new AcmeCancelCalledException(); } } // ... }
- 비동기 메소드 호출의 복수 출력 값을 역으로
전달하십시오.
어떤 경우에는 한 메소드가 여러 부분의 데이터를 역으로 전달해야 합니다.
이 태스크를 수행하는 한 가지 방법은 참조에 의한 전달 시맨틱을 사용하는 것입니다. 이 방식에서 오브젝트는 매개변수로서 메소드로 전달되고 메소드에 의해 업데이트된 후 업데이트된 값을 클라이언트가 사용할 수 있습니다. 이 방식은 비동기 메소드에 대해 작업하지만 최적의 패턴은 아닙니다.
데이터의 여러 부분을 리턴하기 위해, 메소드에 의해 리턴되는 Future 오브젝트 안에 랩퍼를 작성하십시오. 이 방식에서 리턴되어야 하는 여러 부분의 데이터를 보유하는 인스턴스 변수를 포함하는 랩퍼 오브젝트가 정의됩니다. 비동기 메소드는 이런 데이터 부분을 랩퍼 오브젝트로 설정하고 리턴하며, 클라이언트 코드는 Future 오브젝트에서 이 데이터를 검색합니다.
랩퍼 오브젝트에 여러 부분의 데이터를 임베드하는 것은 결과가 사용 가능할 때를 정확하게 식별하는 로컬 또는 원격의 투명한 패턴입니다. 대조적으로, 전통적인 참조에 의한 전달 기법은 결과를 사용 가능한 시기를 판별하는 쉬운 방법을 클라이언트에 제공하지 않습니다. 전달된 오브젝트는 비동기 메소드가 실행할 때까지 업데이트되지 않으며, 클라이언트는 Future.isDone() 또는 Future.get() 메소드를 사용하여 Future 오브젝트를 얻는 방법 이외에 업데이트가 발생한 시기를 판별할 수 없습니다.
// This is the result object that is returned from the asynchronous method. // This object is wrappered in a Future object, and it contains the two pieces of data // that must be returned from the method. class ResultObject { public Boolean myResult; pubilc String myInfo; }
// This is the asynchronous method code that gets the results and returns them. @Asynchronous public Future<ResultObject> asyncMethod1(Object someInputData) { boolean result = doSomeStuff(); String info = doSomeMoreStuff(); ResultObject theResult = new ResultObject(); theResult.myResult = result; theResult.myInfo = info; return new javax.ejb.AsyncResult<ResultObject>(theResult); }
// This is the client code that obtains the ResultObject, and then extracts the needed data from it. Future<ResultObject> myFutureResult = myBeanRef.asyncMethod1(someInputData); ResultObject theResult = myFutureResult.get(); boolean didItWork = theResult.myResult; String explanation = theResult.myInfo;
하위 주제
EJB 비동기 메소드에 대한 클라이언트 프로그래밍 모델
EJB(Enterprise JavaBeans) 3.1 스펙에 명시된 것처럼 로컬 비즈니스, 원격 비즈니스 또는 비인터페이스 보기의 인터페이스 유형을 통해 EJB 비동기 메소드를 호출할 수 있습니다. EJB 2.1 클라이언트 보기 또는 웹 서비스 보기를 통한 호출은 허용되지 않습니다.EJB 비동기 메소드에 대한 클라이언트 프로그래밍 모델
EJB(Enterprise JavaBeans) 3.1 스펙에 명시된 것처럼 로컬 비즈니스, 원격 비즈니스 또는 비인터페이스 보기의 인터페이스 유형을 통해 EJB 비동기 메소드를 호출할 수 있습니다. EJB 2.1 클라이언트 보기 또는 웹 서비스 보기를 통한 호출은 허용되지 않습니다.
관련 태스크:


http://www14.software.ibm.com/webapp/wsbroker/redirect?version=cord&product=was-nd-mp&topic=tejb_clientcode
파일 이름:tejb_clientcode.html