這樣你就可以在無需知道對象位置的情況下獲取和使用對象。SUN對JNDI只提供接口,使用JNDI只需要用到JNDI接口而不必關(guān)心具體實(shí)現(xiàn)。
使用main方法做JNDI的demo時(shí)出現(xiàn)NoInitialContextException是因?yàn)闊o法從System.properties中獲得必要的JNDI參數(shù),在服務(wù)器環(huán)境下,服務(wù)器啟動時(shí)就把這些參數(shù)放到System.properties中了,于是直接new InitialContext()就搞定了。但是在單機(jī)環(huán)境下,可沒有JNDI服務(wù)在運(yùn)行,那就需要手動啟動一個(gè)JNDI服務(wù)。在JDK 5的rt.jar中一共找到了4種SUN自帶的JNDI實(shí)現(xiàn):LDAP,CORBA,RMI,DNS。
這4種JNDI要正常運(yùn)行還需要底層的相應(yīng)服務(wù)。一般我們沒有LDAP或CORBA服務(wù)器,也就無法啟動這兩種JNDI服務(wù),DNS用于查域名的,以后再研究,唯一可以在main()中啟動的就是基于RMI的JNDI服務(wù)。
現(xiàn)在我們就可以在main()中啟動基于RMI的JNDI服務(wù)并且綁一個(gè)對象到JNDI上。注意,我直接把JNDI的相關(guān)參數(shù)放入了System.properties中,這樣,后面的代碼如果要查JNDI,直接new InitialContext()就可以了
在RMI中綁JNDI的限制是,綁定的對象必須是Remote類型,所以就需要自己擴(kuò)展一個(gè)。其實(shí)JNDI還有兩個(gè)Context.SECURITY_PRINCIPAL和Context.SECURITY_CREDENTIAL,如果訪問JNDI需要用戶名和口令,這兩個(gè)也要提供,不過一般用不上。下面是兩個(gè)使用JNDI的簡單例子的代碼,可以直接運(yùn)行。
package com.ellen.jndi;
import java.io.Serializable;
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.util.Date;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
//在RMI中綁JNDI的限制是,綁定的對象必須是Remote類型
class Person implements Remote, Serializable {
private static final long serialVersionUID = -8592182872966400365L;
private String name;
private String pass;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPass() {
return pass;
}
public void setPass(String pass) {
this.pass = pass;
}
public String toString() {
return "name=" + this.getName() + "&pass=" + this.getPass();
}
}
// 在RMI中綁JNDI的限制是,綁定的對象必須是Remote類型
// 外部擴(kuò)展,可以內(nèi)部擴(kuò)展也可以外部擴(kuò)展
class RemoteDate extends Date implements Remote {
};
public class Demo {
public static void initDate() throws NamingException, RemoteException {
// 設(shè)置參數(shù)
LocateRegistry.createRegistry(1099);
System.setProperty(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.rmi.registry.RegistryContextFactory");
System.setProperty(Context.PROVIDER_URL, "rmi://localhost:1099");
InitialContext ctx = new InitialContext();
// 在RMI中綁JNDI的限制是,綁定的對象必須是Remote類型
// 內(nèi)部擴(kuò)展,可以內(nèi)部擴(kuò)展也可以外部擴(kuò)展
class RemoteDate extends Date implements Remote {
}
;
ctx.bind("java:comp/env/systemStartTime", new RemoteDate());
ctx.close();
}
public static void initDate2() throws NamingException, RemoteException {
// 設(shè)置參數(shù)
LocateRegistry.createRegistry(1099);
System.setProperty(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.rmi.registry.RegistryContextFactory");
System.setProperty(Context.PROVIDER_URL, "rmi://localhost:1099");
InitialContext ctx = new InitialContext();
// 自己擴(kuò)展,可以內(nèi)部擴(kuò)展也可以外部擴(kuò)展
// class RemoteDate extends Date implements Remote {
// }
// ;
ctx.bind("java:comp/env/systemStartTime", new RemoteDate());
ctx.close();
}
public static void findDate() throws NamingException, RemoteException {
// 直接使用
InitialContext ctx = new InitialContext();
Date startTime = (Date) ctx.lookup("java:comp/env/systemStartTime");
System.out.println("+++++++++++++++++++++++" + startTime.toString());
ctx.close();
}
public static void jndiDate() throws NamingException, RemoteException {
// Demo.initDate();
Demo.initDate2();
Demo.findDate();
}
public static void initPerson() throws NamingException, RemoteException {
// 設(shè)置參數(shù)
LocateRegistry.createRegistry(1099);
System.setProperty(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.rmi.registry.RegistryContextFactory");
System.setProperty(Context.PROVIDER_URL, "rmi://localhost:1099");
InitialContext ctx = new InitialContext();
// Person person = new Person();
// person.setName("ellen");
// person.setPass("000727");
ctx.bind("java:comp/env/person", new Person());
ctx.close();
}
public static void initPerson2() throws NamingException, RemoteException {
// 設(shè)置參數(shù)
LocateRegistry.createRegistry(1099);
System.setProperty(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.rmi.registry.RegistryContextFactory");
System.setProperty(Context.PROVIDER_URL, "rmi://localhost:1099");
InitialContext ctx = new InitialContext();
Person person = new Person();
person.setName("ellen");
person.setPass("000727");
ctx.bind("java:comp/env/person", person);
ctx.close();
}
public static void findPerson() throws NamingException, RemoteException {
// 直接使用
InitialContext ctx = new InitialContext();
Person person = (Person) ctx.lookup("java:comp/env/person");
System.out.println("------" + person.toString());
System.out.println("------" + person.getName());
System.out.println("------" + person.getPass());
ctx.close();
}
public static void jndiPerson() throws NamingException, RemoteException {
// Demo.initPerson();
Demo.initPerson2();
Demo.findPerson();
}
public static void main(String[] args) throws NamingException, RemoteException {
// 為什么兩個(gè)jndi的例子不能同時(shí)運(yùn)行
// internal error: ObjID already in use
// Demo.jndiDate();
Demo.jndiPerson();
}
}