在容器层面不是只有Queue能实现异步,EJB也异步了!直接上代码,
一、 异步服务端
1.1 异步Bean接口
package com.hp.leo.ejb.session.async;
import java.util.concurrent.Future;
import javax.ejb.Asynchronous;
import javax.ejb.Remote;
@Remote
@Asynchronous
public interface ByeRemote {
public Future<Integer> sayBye() throws Exception;
public Future<String> sayHello() throws Exception;
}
1.2 异步Bean实现
package com.hp.leo.ejb.session.async;
import java.util.concurrent.Future;
import javax.annotation.Resource;
import javax.ejb.AsyncResult;
import javax.ejb.Asynchronous;
import javax.ejb.SessionContext;
import javax.ejb.Stateful;
@Stateful
public class Bye implements ByeRemote {
@Resource
SessionContext myContext;
@Asynchronous
public Future<String> sayHello() throws Exception {
String result = "Hello Leo, welcome to the asynchronous EJB world";
System.out.println("Running Async Bean");
while(myContext.wasCancelCalled() == false){
Thread.sleep(1000);
System.out.println("sayHello method is working");
}
System.out.println("Async Bean Cancelled");
return new AsyncResult<String>(result);
}
@Asynchronous
public Future<Integer> sayBye() throws Exception {
Integer result = 20140730;
//while(myContext.wasCancelCalled() == false){
Thread.sleep(1000);
System.out.println("sayBye method is working");
//}
System.out.println("Async Bean Cancelled");
return new AsyncResult<Integer>(result);
}
}
二、 异步客户端
客户端需要配置jboss-ejb-client.properties如前文《
EJB客户端--让人又爱又恨的JNDI》第一部分介绍。或者将下列代码中的jndiProperties按《
EJB客户端 —去掉jboss-ejb-client.properties》介绍的配置。简单起见,下了客户端使用带有jboss-ejb-client.properties配置文件的方式配置。
package com.hp.leo.client;
import java.util.Hashtable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import com.hp.leo.ejb.session.async.ByeRemote;
public class AsycClientTest {
public static void main(String[] args) throws ExecutionException {
Hashtable<String, String> jndiProperties = new Hashtable<String, String>();
jndiProperties.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
try {
Context context = new InitialContext(jndiProperties);
final String ejbPattern = "ejb:";
final String appName = "";
final String moduleName = "StatefulLifeCycle";
final String distinctName = "";
String jndiName = ejbPattern + appName + "/" + moduleName + "/"
+ distinctName
+ "/Bye!com.hp.leo.ejb.session.async.ByeRemote?stateful";
System.out.println(jndiName);
ByeRemote life = (ByeRemote) context.lookup(jndiName);
try {
Future<String> h = life.sayHello(); // call remote future method
if (h.cancel(true))
System.out.println("future.cancel() returned true");
else
System.out.println("future.cancel() returned false");
System.out.println("5 seconds later the result will be given");
Thread.sleep(5000);
System.out.println(h.get()); // get result asychronize.
Future<Integer> f = life.sayBye(); // call remote future method
Thread.sleep(5000);
System.out.println("Farewell! " + f.get()); // get result asychronize.
} catch (Exception e) {
e.printStackTrace();
}
} catch (NamingException e) {
e.printStackTrace();
}
}
}
异步能用于stateless吗?答案是:能!如果要改造上面的服务端的话,把while(myContext.wasCancelCalled() == false)去掉,客服端不要调用cancel方法即可。