RMIベースのコンパクトで使いやすいフレームです。
もっと読む
最近はrmiの技術があります。Remoteインターフェースを実現する必要があります。RemoteExceptionの異常を抛り出す必要があります。
POJO対象でOK
フレームの核心は三つの種類があります。一つはサービスエンド類RMIEndpointで、一つはクライアント種類RMIProxyFactoryで、一つは汎用インターフェースGenericRmiServiceです。
使い方を見てみます。
ビジネスの使い方:
クライアントの使い方:
使うのは簡単でしょう。Userは普通のインターフェースで、UserImplは普通のPOJOオブジェクトです。
三つのコアクラスの内部を見てみましょう。
サービスポイントクラス:
クライアント代理工場類:
RMI共通インターフェース:
Userインターフェース:
UserImplオブジェクト:
RMIは同時アクセスをサポートしていますので、UserImplはスレッドの安全が必要です。
添付ファイルは完全なソースコードです。
rmi.zip(7.4 KB) ダウンロード回数:104
最近はrmiの技術があります。Remoteインターフェースを実現する必要があります。RemoteExceptionの異常を抛り出す必要があります。
POJO対象でOK
フレームの核心は三つの種類があります。一つはサービスエンド類RMIEndpointで、一つはクライアント種類RMIProxyFactoryで、一つは汎用インターフェースGenericRmiServiceです。
使い方を見てみます。
ビジネスの使い方:
RMIEndpoint.addService(User.class, new UserImpl());
try {
RMIEndpoint.publish(8888);
} catch (Exception e) {
e.printStackTrace();
}
クライアントの使い方:
try {
User user = RMIProxyFactory.getProxy(User.class, "localhost", 8888);
System.out.println(user.say("11111"));
System.out.println(user.say("11111"));
System.out.println(user.say("11111"));
} catch (Exception e) {
e.printStackTrace();
}
使うのは簡単でしょう。Userは普通のインターフェースで、UserImplは普通のPOJOオブジェクトです。
三つのコアクラスの内部を見てみましょう。
サービスポイントクラス:
package com.yuan.common.rmi;
import java.net.InetAddress;
import java.net.MalformedURLException;
import java.net.UnknownHostException;
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.server.UnicastRemoteObject;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.yuan.common.util.ReflectUtil;
public class RMIEndpoint {
private static final Logger LOG = LoggerFactory.getLogger(RMIEndpoint.class);
private static ConcurrentMap serviceMap = new ConcurrentHashMap();
private static String HOSTNAME;
public static void addService(Object service){
serviceMap.put(service.getClass().getName(), service);
}
public static void addService(Class> iface, Object service){
serviceMap.put(iface.getName(), service);
}
/**
* IP
* @param hostName
*/
public static void setHostName(String hostName){
System.setProperty("java.rmi.server.hostname" , hostName);
HOSTNAME = hostName;
}
public static void publish() throws RemoteException, MalformedURLException, UnknownHostException{
publish(1099);
}
public static void publish(int port) throws RemoteException, MalformedURLException, UnknownHostException{
LocateRegistry.createRegistry(port); //
GenericRmiService rmiService = new GenericRmiService(){
private static final long serialVersionUID = 1L;
public Object doService(String serviceName, String methodName, Object[] args) throws RemoteException {
if(serviceMap.containsKey(serviceName)){
Object service = serviceMap.get(serviceName);
try {
return ReflectUtil.execMethod(service, methodName, args);
} catch (Exception e) {
LOG.warn(e.getMessage(), e);
throw new RemoteException(e.getMessage(), e);
}
}
LOG.warn("RMI " + serviceName + " !");
throw new RemoteException("RMI " + serviceName + " !");
}
};
UnicastRemoteObject.exportObject(rmiService, 0); //
if(HOSTNAME == null){
HOSTNAME = InetAddress.getLocalHost().getHostAddress();
}
Naming.rebind("rmi://"+HOSTNAME+":"+port+"/GenericRmiService", rmiService);
}
}
クライアント代理工場類:
package com.yuan.common.rmi;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.rmi.Naming;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
public class RMIProxyFactory {
private static final ConcurrentMap proxyCache = new ConcurrentHashMap();
public static void clearProxyCache(){
proxyCache.clear();
}
public static T getProxy(Class iface, String host, int port) throws Exception{
final String serviceName = getServiceName(iface);
if(proxyCache.containsKey(serviceName)){
return (T)proxyCache.get(serviceName);
}
final GenericRmiService rmiService = (GenericRmiService)Naming.lookup("rmi://"+host+":"+port+"/GenericRmiService");
InvocationHandler h = new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args)throws Throwable {
try {
Object r = rmiService.doService(serviceName, method.getName(), args);
return r;
} catch (Exception e) {
throw new RuntimeException(e.getMessage(), e);
}
}
};
Object proxy = Proxy.newProxyInstance(iface.getClassLoader(), new Class>[]{iface}, h);
proxyCache.put(serviceName, proxy);
return (T) proxy;
}
private static String getServiceName(Class iface) throws IllegalArgumentException, IllegalAccessException{
Field[] fs = iface.getFields();
for(Field f : fs){
if(f.getName().equals("SERVICENAME")){
return (String)f.get(null);
}
}
return iface.getName();
}
}
RMI共通インターフェース:
package com.yuan.common.rmi;
import java.io.Serializable;
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface GenericRmiService extends Remote, Serializable {
public Object doService(String serviceName, String methodName, Object[] args)throws RemoteException;
}
Userインターフェース:
package tmp.rmi;
public interface User {
public String say(String msg);
}
UserImplオブジェクト:
package tmp.rmi;
public class UserImpl implements User {
@Override
public String say(String msg) {
System.out.println("=== " + msg);
System.out.println("=== " + Thread.currentThread());
return "qqqqqqqqq";
}
}
RMIは同時アクセスをサポートしていますので、UserImplはスレッドの安全が必要です。
添付ファイルは完全なソースコードです。