rmi提供了远程方法调用的支持,也就是说方法不是本地的类的方法,你可以通过rmi来直接调用jndi是命名和目录服务,它的意思就是把对象用一个字符串来表示,然后服务器就有一个jndi树,里面有所有对象的字符串(应该叫jndi name),然后只要在初始化上下文环境之后可以通过lookup(String)得到这个对象。我觉得jndi的j2ee中的作用很大,ejb,jta,Datasource或者任何对象都可以使用jndi来处理,把对象管理交了服务器,我们只要知道jndi name就能轻松获取这个对象。
rmi是ejb的基础,作用可想而知
rmi是ejb的基础,作用可想而知
解决方案 »
- 通用权限管理设计
- 单例模式的疑问?多用户同时访问一个实例,会不会出现问题?
- 自动评卷问题
- 请求帮助:hibernate 如何设置子类条件进行查询
- 讨论:在Spring中是否该取消DAO层
- 在java里面,解析XML文档时,怎样获取XML文档头部定义的encoding
- 关于在weblogic用jspsmartupload上传文件保存的路径问题!
- smartupload帮找错,多谢!在线
- 请教:从tomcat 连接SUN 的j2ee server时jndi.properties应该怎么写?
- 错误代码截图,String date2 =new DateFormat().format(date);
- 我在本地建一个服务器(Tomcat)有问题请教!
- Weblogic中使用Servlet验证码引发的问题
再说明一下:
使用rmi以后,你可以拥有对另一台计算机上对象的访问权,就可以调用该远程对象的方法。而且是你必须先将该方法的参数以某种方式传到远程计算机上去,并且该对象必须得到执行该方法的通知,同时返回的值也可以传到你的源机器上。
jndi:用于定位分布式资源。
在j2ee中的作用:非常重要!
工作原理:
在RMI中,调用远程对象的对象被称为客户机对象(Client Object)而远程对象被称为服务器对象(Server Object),同时引入了两种特殊类型对象,存根(stub)和框架(Skelton).存根是代表远程对象的客户端对象,它和远程对象具有相同的接口或方法列表,当客户端调用远程对象时,实际上是由相应的存根对象代理完成,存根通过对象处理远方所有细节,存根通过RMI基础结构将请求转发到远程对象,最后有远程对象执行请求。在服务器端,框架对象处理“远方”的所有细节,因此实际的远程对象不必担心这些细节。也就是说,完全可以像编写本地对象一样来编写远程对象。框架将远程对象从RMI基础结构分离开来。
这个可以看看我的blog: blog.csdn.net/zhutouzipjndi:java命名目录接口!为底层服务提供者实现提供了跨服务的接口!上面都说了!略,呵呵
import java.rmi.Remote;
/**
*
* <p>Title: AbstractRMICall.java </p>
* <p>Description: 所有远程方法调用的父类,处理重试逻辑</p>
* <p>Copyright: Copyright (c) 2004</p>
*/
public abstract class AbstractRMICall
{
/**
* 主业务逻辑方法
* @throws UspMonitorException
* @throws Exception 这里只所以保留Exception,是便于在定义远程接口的时候提供自定义异常
* @return Object
*/
public Object makeCall() throws UspMonitorException,Exception
{
RetryStrategy strategy = getRetryStrategy();
while(strategy.shouldRetry())
{
Remote remoteObject = getRemoteObject();
try
{
return performRemoteCall(remoteObject);
}
catch(RemoteException remoteException)
{
remoteExceptionOccurred(remoteException);
try
{
strategy.remoteExceptionOccurred();
}
catch(RetryException ex)
{
UspLog.error("远程访问对象失败,请确认 IP 是否正确或 RO 是否已经运行"+remoteException.getMessage(),remoteException);
throw new UspMonitorException("public.remote.error");
}
}
catch(CustomAccessException ex)
{
UspLog.error("非法访问异常"+ex.getMessage(),ex);
throw new UspMonitorException("public.remote.deny.access");
}
}
return null;
}
/**
* 模板方法用来获取远程对象
* @throws ServerUnavailable
* @return Remote
*/
protected abstract Remote getRemoteObject() throws UspMonitorException;
/**
* 模板方法用来执行远程调用
* @param remoteObject Remote
* @throws RemoteException
* @throws Exception
* @return Object
*/
protected abstract Object performRemoteCall(Remote remoteObject) throws
RemoteException,CustomAccessException,Exception;
/**
* 获取相应的重试策略
* 默认的管理方式策略应该只重试一次,不需要任何时间间隔
* @return RetryStrategy
*/
protected RetryStrategy getRetryStrategy()
{
return new AdditiveWaitRetryStrategy();
} /**
*
* @param remoteException RemoteException
*/
protected abstract void remoteExceptionOccurred(RemoteException
remoteException) throws UspMonitorException;}
import java.rmi.RemoteException;
/**
*
* <p>Title: CachedRMICall.java </p>
* <p>Description: AbstractRMICall的子类,提供了getRemoteObject方法
* 与remoteExceptionOccurred方法的默认实现</p>
* <p>Copyright: Copyright (c) 2004</p>
*/
public abstract class CachedRMICall
extends AbstractRMICall
{
protected ServerDescription serverDescription; public CachedRMICall(ServerDescription serverDescription)
{
this.serverDescription = serverDescription;
} /**
* 提供获取远程对象的默认实现
* @throws UspMonitorException
* @return Remote
*/
protected Remote getRemoteObject() throws UspMonitorException
{
return RemoteCache.getStubToRemoteObject(serverDescription);
}
/**
* 通过默认实现
* 判断RemoteException里面是否包含了jni异常
* @param remoteException RemoteException
* @throws UspMonitorException
*/
protected void remoteExceptionOccurred(RemoteException remoteException) throws
UspMonitorException
{
if(remoteException.getCause().getCause() instanceof
InvocationTargetException)
{
throw new UspMonitorException("public.remote.jni.error");
}
RemoteCache.removeStubFromCache(serverDescription);
UspLog.info("成功删除serverDescription信息");
}
}/**
*
* <p>Title: RemoteCache.java </p>
* <p>Description: 远程对象保存的容器,提供查询、删除远程对象的能力</p>
* <p>Copyright: Copyright (c) 2004</p>
*/
public class RemoteCache
{
private static final int MAX_SIZE=100;
private static HashMap serverDescriptionsToStubs = new CustomedLinkedHashMap();
/**
* 获取远程对象
* @param serverDescription ServerDescription
* @throws ServerUnavailable
* @return Remote
*/
public static Remote getStubToRemoteObject(ServerDescription serverDescription)
throws UspMonitorException
{
Remote result = (Remote) serverDescriptionsToStubs.get(serverDescription);
if (null == result)
{
result = serverDescription.getRemote();
serverDescriptionsToStubs.put(serverDescription, result); }
return result;
} /**
* 删除远程对象
* @param serverDescription ServerDescription
*/
public static void removeStubFromCache(ServerDescription serverDescription)
{
serverDescriptionsToStubs.remove(serverDescription);
} private static class CustomedLinkedHashMap extends LinkedHashMap
{
protected boolean removeEldestEntry(Map.Entry eldest)
{
return size()>MAX_SIZE;
} } /**
* 删除RO的时候调用此方法清除相应的stub
* @param deviceID int
*/
public static void deleteStubByDeviceID(int deviceID)
{
serverDescriptionsToStubs = new CustomedLinkedHashMap();
}}
import java.rmi.registry.LocateRegistry;/**
*
* <p>Title: RemoteFactory.java</p>
* <p>Description: 用来获取远程对象</p>
* <p>Copyright: Copyright (c) 2004</p>
* <p>Company: </p>
*/
public class RemoteFactory
{
/*用来保存serverDescription对象到Remote对象的映射*/ private RemoteFactory()
{
} /*用来获取远程对象工厂,每个RO对应一个工厂*/ /**
*
* @param ip 服务器的ip
* @param name 远程对象绑定的名字
* @throws UspMonitorException 自定义异常
* @return Remote
*/
public static Remote createRemote(ServerDescription server)
throws UspMonitorException
{
Remote remote=null;
try
{
Registry registry = LocateRegistry.getRegistry(
server.getServerMachine(),server.getRegistryPort());
remote = registry.lookup(server.getServerName());
}
catch(NotBoundException ex1)
{
throw new UspMonitorException("public.remote.notbounderror");
}
catch(RemoteException ex1)
{
throw new UspMonitorException("public.remote.error");
}
return remote;
}public class ServerDescription
{
private String serverMachine;
private String serverName;
private int registryPort;
private String hashString; public String getServerMachine()
{
return serverMachine;
} public int getRegistryPort()
{
return registryPort;
} public void setServerName(String serverName)
{
this.serverName = serverName;
calculateHashstring();
} public void setServerMachine(String serverMachine)
{
this.serverMachine = serverMachine;
calculateHashstring();
} public void setRegistryPort(int registryPort)
{
this.registryPort = registryPort;
calculateHashstring();
} public String getServerName()
{
return serverName; } public ServerDescription(String serverMachine, int registryPort,
String serverName)
{
this.serverMachine = serverMachine;
this.serverName = serverName;
this.registryPort = registryPort;
calculateHashstring();
} public Remote getRemote() throws UspMonitorException
{
Remote result = null;
try
{
result = (Remote) Naming.lookup("rmi://" + serverMachine + ":" +
registryPort + "/" + serverName);
}
catch (RemoteException ex)
{
throw new UspMonitorException("public.remote.error");
}
catch (MalformedURLException ex)
{
UspLog.error("MalformedURLException :你所指定主机 ip 或端口不正确" + ex.getMessage());
throw new UspMonitorException("public.remote.ip.error");
}
catch (NotBoundException ex)
{
UspLog.error("NotBoundException :远程 OS 对象没有绑定,请与管理员联系");
throw new UspMonitorException("public.remote.notbounderror");
}
return result;
} public int hashCode()
{
return hashString.hashCode();
} public boolean equals(Object object)
{
if (! (object instanceof ServerDescription))
{
return false;
}
ServerDescription otherServerDescription = (ServerDescription) object;
return hashString.equals(otherServerDescription.getHashstring());
} private String getHashstring()
{
return hashString;
} private void calculateHashstring()
{
this.hashString = serverMachine + serverName +
String.valueOf(registryPort);
}
}