In JBoss EJB 3.0, you can convert a reference to a local or remote session bean into a reference that will invoke asynchronously on the EJB. This is called obtaining an asychronous proxy or interface. asynchronous interface. Methods called on the asynchronous proxy will be executed asynchronously, and the results can be obtained later on. You obtain an asynchronous proxy by invoking on the org.jboss.ejb3.asynchronous.Asynch.getAsynchronousProxy static method. You pass

package org.jboss.ejb3.asycnhronous;

public class Asynch
{
public static T getAsynchronousProxy(T ejbRef) {…}

public static Future getFutureResult(Object asynchProxy)
}

The asynchronous proxy created will implement the same local/remote interfaces as the original proxy. When you invoke on a method of the asynch proxy, the method will be invoked in the background. If the method has a return value, the value returned by the method will be null or zero depending on the return type. This will not be the true return value of the asynch method so you can just throw this away. To obtain the real result you must obtain org.jboss.aspects.asynch.Future object. This Future object works much the same way a java.util.concurrent.Future object does.

Let us look at an example. We have the following session bean.

package org.acme.test;

@javax.ejb.Remote
public interface Test
{
int perfomHeavyOperation(int i);
String echo(String s);
}

package org.acme.test;

@javax.ejb.Stateless
public class TestBean implements Test
{
public int perfomHeavyOperation(int i)
{
try
{
//Simulate time-consuming operation
Thread.sleep(10000);
return i;
}
catch(Exception e)
{
throw new RuntimeException(e);
}
}

public String echo(String s)
{
return s;
}
}

As you can see there is nothing special about the session bean, now let’s look at the client code. First we look up the remote interface:

InitialContext ctx = new InitialContext();
Test test = (Echo)ctx.lookup(org.acme.test.Test.getName());

We now have a reference to the bean’s normal interface. Calls done on this interface will execute synchronously. The following call to perfomHeavyOperation() will block the client thread for 10 seconds.

int i = test.performHeavyOperation(1);
//i will be 1

Now to demonstrate the asynchronous functionality, we the asynchronous proxy.

Test asynchTest = org.jboss.ejb3.asynchronous.Asynch.getAsynchronousProxy(test);

Calls made on the asynchronous interface will return 0 in the case of a simple return type or null in the case of an Object return type. We will see how to obtain the return value further down.

int j = asynchTest.performHeavyOperation(123);
//j will be 0

The call to perfomHeavyOperation() returns immediately, and our client thread is now free to do other stuff while the business method executes.

//You can do other stuff in client’s thread

Now that we have finished doing things in our thread while the business method has been executing on the server, we obtain the Future which will hold the result of our asynchronous invocation.

Future future = org.jboss.ejb3.asynchronous.Asynch.getFutureResult(asynchTest);

It is important to note that you must call getFutureResult() to obtain the future for the last method call. If you call another method on the asynch proxy, then you will lose the previous Future. The asynchronous invocation might not have finished yet (in case the extra things we did in the client code took < 10 seconds), so we check for this here: while (!future.isDone()) { Thread.sleep(100); } Now that the asynchronous invocation is done, we can obtain its return value from the Future object. int ret = (String)future.get(); //ret will be 123 Note The java.util.concurrent.Future.get() API is blocking and if the asynchronous operation is not yet done, it will wait for the operation to complete. For more details, see: http://docs.jboss.org/ejb3/app-server/reference/build/reference/en/html/jboss_extensions.html#d0e427 http://docs.jboss.org/ejb3/docs/tutorial/asynch/asynch.html http://docs.jboss.org/ejb3/docs/tutorial/1.0.7/html/Asynchronous_Invocations.html

Leave a Reply

电子邮件地址不会被公开。 必填项已用*标注