`

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.util.Hashtable;

import javax.naming.*;

public class NameServiceTest {

	/**
	 * @param args
	 * @throws NamingException 
	 */
	public static void main(String[] args) throws NamingException {
		// TODO Auto-generated method stub
		String fileName = "test1.docx";
		String dirName = "test2";
		Hashtable env = new Hashtable();
		env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.fscontext.RefFSContextFactory");
		env.put(Context.PROVIDER_URL, "file:D:/j2ee/JNDI/publish");
		Context ctx = new InitialContext(env);
		Object file = ctx.lookup(fileName);
		Object dir = ctx.lookup(dirName);
		System.out.println(fileName+" 名称被绑定到"+file);
		System.out.println("file的类型是"+file.getClass());
		System.out.println(dirName+" 名称被绑定到"+dir);
		System.out.println("dir的类型是"+dir.getClass());
		ctx.close();
	}

}

import java.util.Hashtable;

import javax.naming.Binding;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;


public class NameServiceTest2 {

	/**
	 * @param args
	 * @throws NamingException 
	 */
	public static void main(String[] args) throws NamingException {
		// TODO Auto-generated method stub
		String fileName = "previousName";
		String dirName = "dirName";
		Hashtable env = new Hashtable();
		env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.fscontext.RefFSContextFactory");
		env.put(Context.PROVIDER_URL, "file:D:/j2ee/JNDI/publish");
		Context ctx = new InitialContext(env);
		NamingEnumeration <Binding> bindings = ctx.listBindings("");
		while(bindings.hasMoreElements()){
			Binding binding = bindings.next();
			System.out.println(binding.getName()+"-->"+binding.getObject());
		}
		bindings = ctx.listBindings(dirName);
		while(bindings.hasMoreElements()){
			Binding binding = bindings.next();
			System.out.println(binding.getName()+"-->"+binding.getObject());
		}
		ctx.createSubcontext("EdenHazard");
		ctx.createSubcontext("FrankLampard");
		ctx.rename("Essein", "Essein.docx");
		ctx.close();
	}

}
第二部分 RMI
RMI 远程方法调用
一RMI的相关概念
1.首先什么是RMI,远程访问是指网络中的一台计算机可以使用另外一台计算机的服务、对象或是方法。效果就像使用本地的服务、对象或是方法一样。通过远程访问,程序可以在物理位置不同的机器上运行,从而实现分布式计算。
2.为什么要使用RMI,RMI实现了对Socket通信的良好封装,开发者可以直接在本地Java程序中调用远程Java方法,而底层的Socket通信细节对开发者完全透明,这样开发人员就无需去处理那些繁琐的细节。
二RMI编程
1.开发RMI服务器:我的理解是,RMI服务器是提供方法,提供服务的一个类。我们还需要定义一个接口,声明可以被调用的方法,或者说是“暴露”服务这就是面向接口编程,它能提供更好的伸缩性。我们用这个提供服务的类实现之前定义的接口并继承UnicastRemoteObject。继承这个UnicastRemoteObject类就可以“暴露”远程服务。或者我们也可以不继承UnicastRemoteObject,转而使用UnicastRemoteObject.exportObject(client);
2.开发RMI客户端
3.一定要注意RMI的使用是需要JNDI的,RMI服务器的那个具体提供服务的类的实例需要绑定到一个名字,这样客户端才能找到并使用它。
import java.io.Serializable;


public class Person implements Serializable {
	private String name;
	private int age;
	public Person() {
		super();
		// TODO Auto-generated constructor stub
	}
	public Person(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	
}

import java.rmi.Remote;
import java.rmi.RemoteException;


public interface Server extends Remote {
	String helloWorld(String name) throws RemoteException;
	Person getPerson(String name,int age)throws RemoteException;

}
import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.server.UnicastRemoteObject;


public class ServerImpl extends UnicastRemoteObject implements Server {

	/**
	 * @param args
	 */
	public ServerImpl() throws RemoteException{
		
	}
	public String helloWorld (String name) throws RemoteException{
		return name+"您好";
				
	}
	public Person getPerson(String name,int age) throws RemoteException{
		return new Person(name,age);
	}
	public void info(){
		System.out.println("本地方法");
	}
	public static void main(String[] args) throws RemoteException, MalformedURLException {
		// TODO Auto-generated method stub
		Server impl = new ServerImpl();
		LocateRegistry.createRegistry(1099);//创建自己使用的注册表
		Naming.rebind("rmi://:1099/crazyit", impl);//在服务器上注册RMI服务,也可以使用rmiregistry 1099的方法,这个命令如果没有写端口号的话就代表在默认端口1099注册	
          }

}

注意这里Naming的用法,
引用
我们使用Naming类提供直接在对象注册中Naming 类提供在对象注册表中存储和获得远程对远程对象引用的方法。Naming 类的每个方法都可将某个名称作为其一个参数,该名称是使用以下形式的 URL 格式(没有 scheme 组件)的 java.lang.String: //host:port/name
其中 host 是注册表所在的主机(远程或本地),port 是注册表接受调用的端口号,name 是未经注册表解释的简单字符串。host 和 port 两者都是可选项。如果省略了 host,则主机默认为本地主机。如果省略了 port,则端口默认为 1099,该端口是 RMI 的注册表 rmiregistry 使用的“著名”端口。

注册表可由在一个主机上运行的所有服务器共享,需要时个别服务器进程也可以创建和使用自己的注册表需要时个别服务器进程也可以使用下面的函数创建和使用自己的注册表
public static Registry createRegistry(int port)
                               throws RemoteException
创建并导出接受指定 port 请求的本地主机上的 Registry 实例
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.一个小例子就是聊天程序,客户端通过调用服务器端的方法来发送消息,而服务器端则通过回调客户端的方法来显示聊天消息。
分享到:
评论

相关推荐

    j2ee精华学习笔记

    **J2EE精华学习笔记** J2EE,全称为Java 2 Platform, Enterprise Edition,是Java平台上用于构建企业级分布式应用程序的框架。本学习笔记旨在深入解析J2EE的核心概念和技术,帮助读者全面掌握J2EE开发的关键知识。 ...

    Web安全学习笔记.pdf

    《Web安全学习笔记》是一份全面介绍Web安全的资料,涵盖了从基础知识到深入技术的多个层面。本笔记首先概述了Web技术的演进历程及其安全挑战的发展,强调了网络安全的重要性。接下来,它深入探讨了计算机网络的基础...

    ejb 学习笔记6

    ### EJB学习笔记第六部分详解 #### 一、EJB之间的调用 EJB (Enterprise JavaBeans) 是Java EE平台中用于开发分布式企业应用程序的重要组件。在实际开发过程中,经常需要一个EJB调用另一个EJB来实现更复杂的业务...

    EJB学习笔记、运行机制

    【EJB学习笔记、运行机制】 企业级程序(Enterprise Application)是围绕商业目的设计的,具有分布分层的程序架构。这种类型的程序旨在满足大型企业的复杂需求,通常涉及多个组件和层,确保系统的稳定性和可扩展性...

    spring培训学习笔记

    ### Spring培训学习笔记知识点梳理 #### 一、Spring框架概览 - **启动时间与背景**:Spring项目始于2003年2月,最初的基础代码来源于书籍《Expert One-On-One J2EE Design and Development》。 - **核心特性**: -...

    Java分布式应用学习笔记

    Java分布式应用学习笔记 在Java世界中,分布式应用是指由多个独立组件通过网络通信协同工作的系统。这种架构模式常用于构建大规模、高可用性、可扩展的系统。本笔记将深入探讨Java分布式应用的核心概念、技术和实践...

    EJB学习笔记2

    【EJB学习笔记2】 EJB,全称Enterprise JavaBeans,是Java EE(现在被称为Jakarta EE)平台的一部分,主要用于构建可复用的、安全的、可伸缩的服务器端应用程序。EJB标准定义了一组规范,使得开发者可以创建分布式...

    j2ee 学 习 笔 记

    ### J2EE学习笔记 #### 一、J2EE简介及目标 J2EE(Java 2 Platform, Enterprise Edition)是Sun Microsystems公司推出的一种企业级应用程序开发平台标准,旨在为复杂的分布式企业级应用提供一个完整的解决方案。...

    java基础知识第2节

    Javamail是处理电子邮件的API,而JNDI(Java Naming and Directory Interface)用于查找和管理分布式系统的资源。JSP和Servlet是用于构建动态网页的技术,JDBC(Java Database Connectivity)是连接Java应用程序和...

Global site tag (gtag.js) - Google Analytics