JNDI探索

来源:互联网 发布:淘宝美容师工服 编辑:程序博客网 时间:2024/06/10 04:49
        JNDI是J2EE中很重要的一个技术标准接口,但我们在平时的使用上却没有太注意,我们在编程时使用到它的比较多的地方是在查找容器提供DataSource和EJB的home接口的查找上,在这些地方都要用到服务器提供的容器,如jboss,当然在数据源这块我们可以不用容器提供的数据源,而用一些开源项目,如DBCP,即可以用代码直接new出,也可以用Spring,Hibernate等框架的配置文件来设定。

       JNDI与JDBC很相似,它在三层提供了一些API给我们使用,但需要有具体的SPI,即实现者,一般J2EE服务器都有实现,但我们直接使用的话虽然很方便但是必须编写J2EE程序才能使用,这不适合于普通的Java应用程序,例如下面的代码

  InitialContext ctx = new InitialContext();
  return ctx.lookup("java:.......");

在服务器环境下的J2EE程序中没有问题,但在普通的应用程序中就会抛出NoInitialContextException,原因很简单因为你没有JNDI的SPI。在应用程序中可以有两种方式来使用JNDI,当然在这其中都需要具体SPI的jar包。

第一种是在创建InitialContext的时候还要传一个Hashtable或者Properties,如下以用weblogic的SPI为例

 

Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory");
env.put(Context.PROVIDER_URL,"t3://localhost:7001");
InitialContext ctx = new InitialContext(env);

如果是在jboss下用代码来调用,则factory要用jboss的了。

另一种方式是对System对象setProperty一些JNDI参数,实际上我们用服务器提供的JNDI也是这样,在服务器环境下,服务器启动时就把这些参数放到System.properties中了,于是直接new InitialContext()就搞定了,不要搞env那么麻烦。

在单机环境下,可没有JNDI服务在运行,那就必须手动启动一个JNDI服务。在JDK 5的rt.jar中一共有4种SUN自带的JNDI实现:

LDAP,CORBA,RMI,DNS。

这4种JNDI要正常运行还需要底层的相应服务。一般我们没有LDAP或CORBA服务器,也就无法启动这两种JNDI服务,DNS用于查域名的,以后再研究,唯一可以在main()中启动的就是基于RMI的JNDI服务。

现在我们就在main()中启动基于RMI的JNDI服务并且绑一个Date对象到JNDI上:

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();
class RemoteDate extends Date implements Remote {};
ctx.bind("java:comp/env/systemStartTime", new RemoteDate());
ctx.close();

注意,我们直接把JNDI的相关参数放入了System.properties中,这样,后面的代码如果要查JNDI,直接new InitialContext()就可以了。

另外我们还可以用File System做为naming service。以下为例子:

String name = "C:/aaa.txt"; 

env.put(Context.INITIAL_CONTEXT_FACTORY,"com.sun.jndi.fscontext.RefFSContextFactory"); 

 Context ctx = new InitialContext(env);

Object obj = ctx.lookup(name);