JNDI RMI学习笔记
学习李刚老师的经典JavaEE企业实战中的JNDI,RMI部分,做了一些笔记和思考
第一部分 JNDI
一JNDI的概念,
1.JNDI不依赖任何独立的命名目录服务器,不管采用哪种命名目录服务器,应用程序都可通过统一的JNDI接口来调用。也就是说JAVA为某种服务制定规范,而具体的实现则由不同的厂商自己提供实现,这样开发者只要面向这种规范的接口编程,以此屏蔽掉底层服务器之间存在的差异。类似JDBC,JMS。JNDI给出了实现的规范,和相应操作的API。
2.命名服务:为什么要有命名服务,我的理解是这样的,就是不同的系统,它对于相同的对象可能有不同的名字和不同的起名格式,那么JNDI就屏蔽掉这个细节,给其以相同的名字,保存名称和对象之间的关联。这样开发者就可以使用相同的方式去访问各种系统中的对象。
3.目录服务,在命名服务上的扩展,不仅保存名称和对象之间的关联,而且还会保存对象的各种属性。这样开发者就可以操作对象的属性。比如说电话薄,我们通过用户名(JNDI名)找到用户(对象),并且查看该对象的地址、电话号码等属性值。
4.LDAP,命名和目录服务的一种实现。
二JNDI的基本概念
1.binding绑定,为对象起名字,专业说法是将一个名字绑定某个对象。
2.Context(上下文):就是绑定的集合。
3.Naming System(命名系统):遵循某种命名规则的绑定系统。
4.Naming Service(命名服务):命名服务就是命名系统对外提供的服务和功能。命名服务的最大功能就是允许通过名字来访问与之绑定的对象。
5.Directory Service(目录服务):见上面一节
三JNDI编程的步骤
(一)典型用法
1.创建Context对象
使用InitialContext()方法来创建实例,InitialContext()有两个构造方法,InitialContext(),InitialContext(HashTable<?,?>environment)如果使用第一个构造方法的话,它必须从系统属性中读到合适的Context属性来执行初始化,一般System.getProperties()方法返回值。
java.naming.factory.initial:该key的值应该为初始化Context工厂类。
java.naming.provider.url 该key值应该为Context服务提供者的URL
2.调用Context对象的lookup方法根据JNDI名称查找被绑定对象。或者调用bind方法来执行绑定。
lookup接受被绑定的JNDI名,返回与之绑定的对象。
3.关闭Context对象。
(二)经常使用的函数
1.查找:ServiceBean service = (ServiceBean)ctx.lookup("service");
2.绑定:ServiceBean service = new ServiceBean();
ctx.bind("service",service);
3.list和listBindings,列出当前Context或其他SubContext下的所有绑定关系,有参数的话,就代表列出该Context下的那个参数指定的子文件的所有绑定关系,没有的话就列出Context下的所有绑定关系
4.createSubContext和destroySubContext,创建删除子Context,如果在文件系统中,那么这个就是创建和删除子文件夹。
5.rename,注意这个不同于rebind,这个就是把绑定的名字更换掉,而rebind是把绑定的对象更换掉。
import java.rmi.Naming;public class RMIClient {public static void main(String [] args) throws Exception{Server ser = (Server)Naming.lookup("rmi://:1099/crazyit");System.out.println(ser.helloWorld("haha"));System.out.println(ser.getPerson("feng",23));}}
三RMI基本原理
1.客户端调用远程服务器段的java方法只是一个假象,其真实情况是:客户端的调用请求时发送给本地的Stub对象的。由Stub对象和Skeleton对象来建立底层的网络通信,stub和skeleton分别对应客户端和服务器端的代理。具体内容可参见李刚老师的这本书的有关内容。
四开发同时作为客户端和服务器端的RMI程序
1.一般来说,是客户端调用服务器端的方法,服务器端不会主动调用客户端的方法,因为客户端往往不会执行JNDI绑定,客户端往往没有固定的IP,那么我们怎么样才能让服务器端调用客户端的方法呢,我的理解是,首先客户端先调用服务器端的方法,并在调用时,在调用函数中增加一个客户端的引用,这样我们在编写服务器端的方法时就可以利用这个参数来回调客户端的方法,这样我们在调用服务器端方法时,服务器端也会回调客户端的方法,以此来实现一个既能做客户端又能做服务器端的方法。
2.一个小例子就是聊天程序,客户端通过调用服务器端的方法来发送消息,而服务器端则通过回调客户端的方法来显示聊天消息。