| 當
客戶端要使用Session
Bean,而客戶端位於容器以外的JVM時,則必須定義其服務介面為遠端介面,即使用@Remote標示,容器會在部署之後,在Bytecode上加入繼
承java.rmi.Remote的動作,你也可以直接自行繼承java.rmi.Remote,例如: @Remote
public interface HelloBean extends java.rmi.Remote { .... } 不在程式上直接撰寫繼承java.rmi.Remote的好處之一,是不需要撰寫丟出java.rmi.RemoteException,由於實際上 Bean的取得會是透過RMI機制,因此你的方法呼叫若有參數或傳回值,它們都必須實作java.io.Serializable介面。 由於@Remote底層會使用RMI,所以會有RMI呼叫的負擔,若可以的話,應避免使用@Remote而使用@Local,當客戶端使用Session Bean,而客戶端與Session Bean是位於同一個容器(同一個JVM)時,則可以標示Session Bean為@Local。 一個Session Bean的服務介面不能同時是遠端及本地介面,也就是不能同時標示為@Remote及@Local,即以下是不允許的: @Local
@Remote public interface HelloBean { .... } 若要讓一個Session Bean實作同時是遠端及本地,則你要分別定義遠端介面及本地介面,例如: @Local
public interface HelloBeanLocal { String doHello(String message); .... } @Remote public interface HelloBeanRemote { String doHello(String message); .... } 然後讓Session Bean同時實作這兩個介面,例如: @Stateless(name="ejb/HelloFacade")
public class HelloBeanImpl implements HelloBeanLocal, HelloBeanRemote { public String doHello(String message) { return message + "processed...."; } } 本地介面取用時可以使用HelloBeanLocal介面,例如: @EJB
private HelloBeanLocal hello; 而遠端介面取用時可以使用HelloBeanRemote介面: InitialContext context = new InitialContext();
Object obj = context.lookup("onlyfun.caterpillar.HelloBeanRemote"); HelloBeanRemote hello = (HelloBeanRemote) PortableRemoteObject.narrow(obj, HelloBeanRemote.class); 您也可以在定義介面時,不使用@Local、@Remote,例如: public interface HelloBeanLocal {
String doHello(String message); .... } public interface HelloBeanRemote { String doHello(String message); .... } 而在實作Session Bean時再加以指定@Local、@Remote: @Local({HelloBeanLocal.class})
@Remote({HelloBeanRemote.class}) @Stateless(name="ejb/HelloFacade") public class HelloBeanImpl implements HelloBean { public String doHello(String message) { return message + "processed...."; } } |