在容器层面不是只有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方法即可。


Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐