JNDI
(The Java Naming and Directory Interface
,
Java
命名和目录接口
)
是一组在
Java
应用中访问命名和目录服务的
API
。为开发人员提供了查找和访问各种命名和目录服务的通用、统一的方式。借助于
JNDI
提供的接口,能够通过名字定位用户、机器、网络、对象服务等。
命名服务
:就像
DNS
一样,通过命名服务器提供服务,大部分的
J2EE
服务器都含有命名服务器。
目录服务
:一种简化的
RDBMS
系统,通过目录具有的属性保存一些简单的信息。目录服务通过目录服务器实现,比如微软
ACTIVE DIRECTORY
等。
JNDI
的好处
:
(
1
)包含大量命名和目录服务,可以使用相同
API
调用访问任何命名或目录服务。
(
2
)可以同时连接多个命名和目录服务。
(
3
)允许把名称同
JAVA
对象或资源关联起来,不必知道对象或资源的物理
ID
。
(
4
)使用通用接口访问不同种类的目录服务
(
5
)使得开发人员能够集中使用和实现一种类型的命名或目录服务客户
API
上。
上下文
:由
0
或多个绑定构成。比如
java/MySql
,
java
为上下文(
context
),
MySql
为命名
子上下文
(
subConext
):上下文下的上下文。比如
MyJNDITree/ejb/helloBean
,
ejb
为子上下文
。
因为
JNDI
是一组接口,所以我们只需根据接口规范编程就可以。要通过
JNDI 进行资源访问,我们必须设置初始化上下文的参数
,主要是设置
JNDI 驱动的类名(java.naming.factory.initial) 和提供命名服务的URL (java.naming.provider.url)
。
因为
Jndi
的实现产品有很多。所以
java.naming.factory.initial
的值因提供
JNDI
服务器的不同而不同
,
java.naming.provider.url
的值包括提供命名服务的主机地址和端口号。
访问
Jboss
服务器的例子代码:
Properties props = new Properties();
props.setProperty("java.naming.factory.initial", "org.jnp.interfaces.NamingContextFactory");
props.setProperty("java.naming.provider.url", "localhost:1099");
InitialContext = new InitialContext(props);
HelloWorld helloworld = (HelloWorld) ctx.lookup("HelloWorldBean/remote");
访问
Sun
应用服务器的例子代码:
Properties props = new Properties();
props.setProperty("java.naming.factory.initial",
"com.sun.enterprise.naming.SerialInitContextFactory");
props.setProperty("java.naming.provider.url", "localhost:3700");
InitialContext = new InitialContext(props);
HelloWorld helloworld = (HelloWorld) ctx.lookup("com.foshanshop.ejb3.HelloWorld");
访问 Weblogic10 应用服务器的例子代码:
Properties props = new Properties();
props.setProperty("java.naming.factory.initial", "weblogic.jndi.WLInitialContextFactory");
props.setProperty("java.naming.provider.url", "t3://localhost:7001");
InitialContext = new InitialContext(props);
HelloWorld helloworld = (HelloWorld) ctx.lookup("HelloWorldBean#com.foshanshop.ejb3.HelloWorld");
JBOSS
环境下
JNDI
树的命名约定:
(
1
)
java:copm
这个上下文环境和其子上下文环境仅能被与之相关的特定应用组件访问和使用
(
2
)
java
: 子上下文环境和绑定的对象只能被
Jboss
服务器虚拟机内的应用访问
(
3
)其他上下文环境 只要实现序列化就可以被远程用户调用。
当你把EJB发布到JBOSS后,
你就可以在
jboss 的管理平台查看她们的JNDI 名
,输入下面
URL http://localhost:8080/jmx-console/
,
点击“
service=JNDIView
” link,在出现的page里找到“
List of MBean operations:
”栏的“list()”方法,click “Invoke”button,就会看到下面的界面
在上图中可以看见
HelloWorld
会话
Bean
的
JNDI
路径,
JNDI
路径名的组成规则是“上层名称
/
下层名称
,每层之间以
”/”
分隔
。
HelloWorld
会话
Bean
的
JNDI
路径名是:
HelloWorldBean/remote
下面要重点说明一下
Jboss EJB JNDI 名称默认的命名规则
,命名规则如下:
1>
如果
EJB
打包进
后缀为
*.ear
的
J2EE
发布文件
,默认的
JNDI
路径名称是
访问本地接口:
EAR-FILE-BASE-NAME/EJB-CLASS-NAME/local
访问远程接口:
EAR-FILE-BASE-NAME/EJB-CLASS-NAME/remote
例:
EJB HelloWorld
打包进名为
HelloWorld.ear
的
J2EE
应用,访问她远程接口的
JNDI
名是:
HelloWorld/HelloWorldBean/remote
2>
如果
EJB
应用
打包成后缀为
*.jar
的发布文件
,
默认的
JNDI
路径名称是
访问本地接口:
EJB-CLASS-NAME/local
访问远程接口:
EJB-CLASS-NAME/remote
例:
HelloWorld
应用打包成
HelloWorld.jar
文件,访问她远程接口的
JNDI
名称是:
HelloWorldBean/remote
注意:
EJB-CLASS-NAME
是不带包名的
,如
com.foshanshop.ejb3.impl.HelloWorldBean
只需取
HelloWorldBean
。
目前网上很多教材获取
JNDI
路径名的方式不适用在
jboss
下,如:
HelloWorld helloworld = (HelloWorld) ctx.lookup(HelloWorld.class.getName());
这种方式适用于
Sun Application Server
及
glassfish
自定义JNDI 命名
默认的
JNDI
命名规则上面已经介绍过,但有些情况下需要自定义名称。在
Jboss 中
要自定义
JNDI
名称,可以使用
@LocalBinding
和
@RemoteBinding
注释
关键代码(只需要在bean interface前加binding注释):
import org.jboss.annotation.ejb.RemoteBinding;
...
@Remote
@RemoteBinding (jndiBinding="testbinding/myAccount")
public interface MyAccount extends Serializable {
publicint Add(int a, int b);
publicint getResult() ;
}
那么在client端调用上面的EJB的代码为:
InitialContext ctx = new InitialContext(props);
MyAccount bean1 = (MyAccount) ctx.lookup("testbinding/myAccount");